Commit 2f12dbf1 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Paul Walmsley
Browse files

riscv: don't use the rdtime(h) pseudo-instructions



If we just use the CSRs that these map to directly the code is simpler
and doesn't require extra inline assembly code.  Also fix up the top-level
comment in timer-riscv.c to not talk about the cycle count or mention
details of the clocksource interface, of which this file is just a
consumer.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarAtish Patra <atish.patra@wdc.com>
Signed-off-by: default avatarPaul Walmsley <paul.walmsley@sifive.com>
parent f5bf645d
Loading
Loading
Loading
Loading
+21 −23
Original line number Diff line number Diff line
@@ -6,43 +6,41 @@
#ifndef _ASM_RISCV_TIMEX_H
#define _ASM_RISCV_TIMEX_H

#include <asm/param.h>
#include <asm/csr.h>

typedef unsigned long cycles_t;

static inline cycles_t get_cycles_inline(void)
static inline cycles_t get_cycles(void)
{
	cycles_t n;

	__asm__ __volatile__ (
		"rdtime %0"
		: "=r" (n));
	return n;
	return csr_read(CSR_TIME);
}
#define get_cycles get_cycles_inline
#define get_cycles get_cycles

#ifdef CONFIG_64BIT
static inline uint64_t get_cycles64(void)
static inline u64 get_cycles64(void)
{
	return get_cycles();
}
#else
static inline uint64_t get_cycles64(void)
#else /* CONFIG_64BIT */
static inline u32 get_cycles_hi(void)
{
	return csr_read(CSR_TIMEH);
}

static inline u64 get_cycles64(void)
{
	u32 lo, hi, tmp;
	__asm__ __volatile__ (
		"1:\n"
		"rdtimeh %0\n"
		"rdtime %1\n"
		"rdtimeh %2\n"
		"bne %0, %2, 1b"
		: "=&r" (hi), "=&r" (lo), "=&r" (tmp));
	u32 hi, lo;

	do {
		hi = get_cycles_hi();
		lo = get_cycles();
	} while (hi != get_cycles_hi());

	return ((u64)hi << 32) | lo;
}
#endif
#endif /* CONFIG_64BIT */

#define ARCH_HAS_READ_CURRENT_TIMER

static inline int read_current_timer(unsigned long *timer_val)
{
	*timer_val = get_cycles();
+4 −13
Original line number Diff line number Diff line
@@ -2,6 +2,10 @@
/*
 * Copyright (C) 2012 Regents of the University of California
 * Copyright (C) 2017 SiFive
 *
 * All RISC-V systems have a timer attached to every hart.  These timers can be
 * read from the "time" and "timeh" CSRs, and can use the SBI to setup
 * events.
 */
#include <linux/clocksource.h>
#include <linux/clockchips.h>
@@ -12,19 +16,6 @@
#include <asm/smp.h>
#include <asm/sbi.h>

/*
 * All RISC-V systems have a timer attached to every hart.  These timers can be
 * read by the 'rdcycle' pseudo instruction, and can use the SBI to setup
 * events.  In order to abstract the architecture-specific timer reading and
 * setting functions away from the clock event insertion code, we provide
 * function pointers to the clockevent subsystem that perform two basic
 * operations: rdtime() reads the timer on the current CPU, and
 * next_event(delta) sets the next timer event to 'delta' cycles in the future.
 * As the timers are inherently a per-cpu resource, these callbacks perform
 * operations on the current hart.  There is guaranteed to be exactly one timer
 * per hart on all RISC-V systems.
 */

static int riscv_clock_next_event(unsigned long delta,
		struct clock_event_device *ce)
{