static void arch_timer_stop(void) { unsigned long ctrl; ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); ctrl &= ~ARCH_TIMER_CTRL_ENABLE; arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); }
static inline void set_next_event(const int access, unsigned long evt, struct clock_event_device *clk) { unsigned long ctrl; ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk); }
static inline void set_next_event(const int access, unsigned long evt) { unsigned long ctrl; ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt); arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); }
static __always_inline int timer_shutdown(const int access, struct clock_event_device *clk) { unsigned long ctrl; ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl &= ~ARCH_TIMER_CTRL_ENABLE; arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); return 0; }
static inline void timer_set_mode(const int access, int mode, struct clock_event_device *clk) { unsigned long ctrl; switch (mode) { case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl &= ~ARCH_TIMER_CTRL_ENABLE; arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); break; case CLOCK_EVT_MODE_ONESHOT: ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl |= ARCH_TIMER_CTRL_ENABLE; arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); break; default: break; } }
static inline irqreturn_t timer_handler(const int access, struct clock_event_device *evt) { unsigned long ctrl; ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, evt); if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { ctrl |= ARCH_TIMER_CTRL_IT_MASK; arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, evt); evt->event_handler(evt); return IRQ_HANDLED; } return IRQ_NONE; }
static inline void timer_set_mode(const int access, int mode) { unsigned long ctrl; switch (mode) { case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); ctrl &= ~ARCH_TIMER_CTRL_ENABLE; arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); break; default: break; } }
static int arch_timer_set_next_event(unsigned long evt, struct clock_event_device *unused) { unsigned long ctrl; ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IMASK; arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt); arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); return 0; }
static irqreturn_t arch_timer_handle_irq(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; unsigned long ctrl; ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); if (ctrl & ARCH_TIMER_CTRL_ISTATUS) { ctrl |= ARCH_TIMER_CTRL_IMASK; arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); evt->event_handler(evt); return IRQ_HANDLED; } return IRQ_NONE; }
static __always_inline void fsl_a008585_set_next_event(const int access, unsigned long evt, struct clock_event_device *clk) { unsigned long ctrl; u64 cval = evt + arch_counter_get_cntvct(); ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; if (access == ARCH_TIMER_PHYS_ACCESS) write_sysreg(cval, cntp_cval_el0); else if (access == ARCH_TIMER_VIRT_ACCESS) write_sysreg(cval, cntv_cval_el0); arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); }
static void __init arch_timer_calibrate(void) { if (arch_timer_rate == 0) { arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0); arch_timer_rate = arch_timer_reg_read(ARCH_TIMER_REG_FREQ); /* Check the timer frequency. */ if (arch_timer_rate == 0) panic("Architected timer frequency is set to zero.\n" "You must set this in your .dts file\n"); } /* Cache the sched_clock multiplier to save a divide in the hot path. */ sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; pr_info("Architected local timer running at %u.%02uMHz.\n", arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100); }