Skip to content

Commit

Permalink
arch/risc-v/src/common/riscv_mtimer.c: Change risc-v tick timer to us…
Browse files Browse the repository at this point in the history
…e oneshot timer tick_ operations

As the riscv_mtimer is just a OS tick timer, use the interface ment
for the purpose.

Signed-off-by: Jukka Laitinen <[email protected]>
  • Loading branch information
jlaitine committed Mar 6, 2025
1 parent 6303c11 commit 6838f8c
Showing 1 changed file with 24 additions and 29 deletions.
53 changes: 24 additions & 29 deletions arch/risc-v/src/common/riscv_mtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,25 @@ struct riscv_mtimer_lowerhalf_s
****************************************************************************/

static int riscv_mtimer_max_delay(struct oneshot_lowerhalf_s *lower,
struct timespec *ts);
clock_t *ticks);
static int riscv_mtimer_start(struct oneshot_lowerhalf_s *lower,
oneshot_callback_t callback, void *arg,
const struct timespec *ts);
clock_t ticks);
static int riscv_mtimer_cancel(struct oneshot_lowerhalf_s *lower,
struct timespec *ts);
clock_t *ticks);
static int riscv_mtimer_current(struct oneshot_lowerhalf_s *lower,
struct timespec *ts);
clock_t *ticks);

/****************************************************************************
* Private Data
****************************************************************************/

static const struct oneshot_operations_s g_riscv_mtimer_ops =
{
.max_delay = riscv_mtimer_max_delay,
.start = riscv_mtimer_start,
.cancel = riscv_mtimer_cancel,
.current = riscv_mtimer_current,
.tick_start = riscv_mtimer_start,
.tick_current = riscv_mtimer_current,
.tick_max_delay = riscv_mtimer_max_delay,
.tick_cancel = riscv_mtimer_cancel,
};

/****************************************************************************
Expand Down Expand Up @@ -172,7 +172,7 @@ static void riscv_mtimer_set_mtimecmp(struct riscv_mtimer_lowerhalf_s *priv,
* lower An instance of the lower-half oneshot state structure. This
* structure must have been previously initialized via a call to
* oneshot_initialize();
* ts The location in which to return the maximum delay.
* ticks The location in which to return the maximum delay.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned
Expand All @@ -181,10 +181,9 @@ static void riscv_mtimer_set_mtimecmp(struct riscv_mtimer_lowerhalf_s *priv,
****************************************************************************/

static int riscv_mtimer_max_delay(struct oneshot_lowerhalf_s *lower,
struct timespec *ts)
clock_t *ticks)
{
ts->tv_sec = UINT32_MAX;
ts->tv_nsec = NSEC_PER_SEC - 1;
*ticks = (clock_t)UINT64_MAX;

return 0;
}
Expand All @@ -201,7 +200,7 @@ static int riscv_mtimer_max_delay(struct oneshot_lowerhalf_s *lower,
* oneshot_initialize();
* handler The function to call when when the oneshot timer expires.
* arg An opaque argument that will accompany the callback.
* ts Provides the duration of the one shot timer.
* ticks Provides the duration of the one shot timer.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned
Expand All @@ -211,19 +210,20 @@ static int riscv_mtimer_max_delay(struct oneshot_lowerhalf_s *lower,

static int riscv_mtimer_start(struct oneshot_lowerhalf_s *lower,
oneshot_callback_t callback, void *arg,
const struct timespec *ts)
clock_t ticks)
{
struct riscv_mtimer_lowerhalf_s *priv =
(struct riscv_mtimer_lowerhalf_s *)lower;
irqstate_t flags;
uint64_t mtime;
clock_t current;
uint64_t alarm;

flags = up_irq_save();

mtime = riscv_mtimer_get_mtime(priv);
alarm = mtime + ts->tv_sec * priv->freq +
ts->tv_nsec * priv->freq / NSEC_PER_SEC;
current = mtime * TICK_PER_SEC / priv->freq;
alarm = (current + ticks) * priv->freq / TICK_PER_SEC;

priv->alarm = alarm;
priv->callback = callback;
Expand All @@ -248,7 +248,7 @@ static int riscv_mtimer_start(struct oneshot_lowerhalf_s *lower,
* lower Caller allocated instance of the oneshot state structure. This
* structure must have been previously initialized via a call to
* oneshot_initialize();
* ts The location in which to return the time remaining on the
* ticks The location in which to return the time remaining on the
* oneshot timer. A time of zero is returned if the timer is
* not running.
*
Expand All @@ -260,13 +260,12 @@ static int riscv_mtimer_start(struct oneshot_lowerhalf_s *lower,
****************************************************************************/

static int riscv_mtimer_cancel(struct oneshot_lowerhalf_s *lower,
struct timespec *ts)
clock_t *ticks)
{
struct riscv_mtimer_lowerhalf_s *priv =
(struct riscv_mtimer_lowerhalf_s *)lower;
uint64_t mtime;
uint64_t alarm;
uint64_t nsec;
irqstate_t flags;

flags = up_irq_save();
Expand All @@ -277,9 +276,8 @@ static int riscv_mtimer_cancel(struct oneshot_lowerhalf_s *lower,

riscv_mtimer_set_mtimecmp(priv, mtime + UINT64_MAX);

nsec = (alarm - mtime) * NSEC_PER_SEC / priv->freq;
ts->tv_sec = nsec / NSEC_PER_SEC;
ts->tv_nsec = nsec % NSEC_PER_SEC;
*ticks = alarm * TICK_PER_SEC / priv->freq -
mtime * TICK_PER_SEC / priv->freq;

priv->alarm = 0;
priv->callback = NULL;
Expand All @@ -300,7 +298,7 @@ static int riscv_mtimer_cancel(struct oneshot_lowerhalf_s *lower,
* lower Caller allocated instance of the oneshot state structure. This
* structure must have been previously initialized via a call to
* oneshot_initialize();
* ts The location in which to return the current time. A time of zero
* ticks The location in which to return the current time. A time of zero
* is returned for the initialization moment.
*
* Returned Value:
Expand All @@ -310,18 +308,15 @@ static int riscv_mtimer_cancel(struct oneshot_lowerhalf_s *lower,
****************************************************************************/

static int riscv_mtimer_current(struct oneshot_lowerhalf_s *lower,
struct timespec *ts)
clock_t *ticks)
{
struct riscv_mtimer_lowerhalf_s *priv =
(struct riscv_mtimer_lowerhalf_s *)lower;
uint64_t mtime = riscv_mtimer_get_mtime(priv);
uint64_t left;

ts->tv_sec = mtime / priv->freq;
left = mtime - ts->tv_sec * priv->freq;
ts->tv_nsec = NSEC_PER_SEC * left / priv->freq;
*ticks = mtime * TICK_PER_SEC / priv->freq;

return 0;
return OK;
}

static int riscv_mtimer_interrupt(int irq, void *context, void *arg)
Expand Down

0 comments on commit 6838f8c

Please sign in to comment.