drivers/timer: Reworked NRF driver with tickless support

Reworked using the older hardware interface code, but with an
implementation of the new API only.  Much smaller & simpler.

As yet, tested (manually) only on a nrf52_pca10056 board.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c
index 3a4d315..c8d06d6 100644
--- a/drivers/timer/nrf_rtc_timer.c
+++ b/drivers/timer/nrf_rtc_timer.c
@@ -1,513 +1,76 @@
 /*
  * Copyright (c) 2016-2017 Nordic Semiconductor ASA
+ * Copyright (c) 2018 Intel Corporation
  *
  * SPDX-License-Identifier: Apache-2.0
  */
 
 #include <soc.h>
 #include <clock_control.h>
-#include <system_timer.h>
 #include <drivers/clock_control/nrf5_clock_control.h>
+#include <system_timer.h>
 #include <sys_clock.h>
-#include "nrf_rtc.h"
+#include <nrf_rtc.h>
+#include <spinlock.h>
 
-#include "legacy_api.h"
+#define RTC NRF_RTC1
 
-/*
- * Convenience defines.
- */
-#define SYS_CLOCK_RTC          NRF_RTC1
-#define RTC_COUNTER            nrf_rtc_counter_get(SYS_CLOCK_RTC)
-#define RTC_CC_IDX             0
-#define RTC_CC_EVENT           SYS_CLOCK_RTC->EVENTS_COMPARE[RTC_CC_IDX]
+#define COUNTER_MAX 0x00ffffff
+#define CYC_PER_TICK (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC	\
+		      / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
+#define MAX_TICKS ((COUNTER_MAX - CYC_PER_TICK) / CYC_PER_TICK)
 
-/* Minimum delta between current counter and CC register that the RTC is able
- * to handle
- */
-#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
-#define RTC_MIN_DELTA          1
-#else
-#define RTC_MIN_DELTA          2
-#endif
+#define MIN_DELAY 32
 
-#define RTC_MASK               0x00FFFFFF
-/* Maximum difference for RTC counter values used. Half the maximum value is
- * selected to be able to detect overflow (a negative value has the same
- * representation as a large positive value).
- */
-#define RTC_HALF               (RTC_MASK / 2)
+static struct k_spinlock lock;
 
-/*
- * rtc_past holds the value of RTC_COUNTER at the time the last sys tick was
- * announced, in RTC ticks. It is therefore always a multiple of
- * sys_clock_hw_cycles_per_tick().
- */
-static u32_t rtc_past;
+static u32_t last_count;
 
-static s32_t _sys_idle_elapsed_ticks = 1;
-
-#ifdef CONFIG_TICKLESS_IDLE
-/*
- * Holds the maximum sys ticks the kernel expects to see in the next
- * z_clock_announce(_sys_idle_elapsed_ticks).
- */
-static u32_t expected_sys_ticks;
-#endif /* CONFIG_TICKLESS_IDLE */
-
-#ifdef CONFIG_TICKLESS_KERNEL
-s32_t _get_max_clock_time(void);
-#endif /* CONFIG_TICKLESS_KERNEL */
-
-/*
- * Set RTC Counter Compare (CC) register to a given value in RTC ticks.
- */
-static void rtc_compare_set(u32_t rtc_ticks)
+static u32_t counter_sub(u32_t a, u32_t b)
 {
-	u32_t rtc_now;
-
-	/* Try to set CC value. We assume the procedure is always successful. */
-	nrf_rtc_cc_set(SYS_CLOCK_RTC, RTC_CC_IDX, rtc_ticks);
-	rtc_now = RTC_COUNTER;
-
-	/* The following checks if the CC register was set to a valid value.
-	 * The first test checks if the distance between the current RTC counter
-	 * and the value (in the future) set in the CC register is too small to
-	 * guarantee a compare event being triggered.
-	 * The second test checks if the current RTC counter is higher than the
-	 * value written to the CC register, i.e. the CC value is in the past,
-	 * by checking if the unsigned subtraction wraps around.
-	 * If either of the above are true then instead of waiting for the CC
-	 * event to trigger in the form of an interrupt, trigger it directly
-	 * using the NVIC.
-	 */
-	if ((((rtc_ticks - rtc_now) & RTC_MASK) < RTC_MIN_DELTA) ||
-	    (((rtc_ticks - rtc_now) & RTC_MASK) > RTC_HALF)) {
-		NVIC_SetPendingIRQ(NRF5_IRQ_RTC1_IRQn);
-	}
-}
-#ifndef CONFIG_TICKLESS_KERNEL
-/*
- * @brief Announces the number of sys ticks, if any, that have passed since the
- * last announcement, and programs the RTC to trigger the interrupt on the next
- * sys tick.
- *
- * This function is not reentrant. It is called from:
- *
- * * z_clock_idle_exit(), which in turn is called with interrupts disabled when
- * an interrupt fires.
- * * rtc1_nrf5_isr(), which runs with interrupts enabled but at that time the
- * device cannot be idle and hence z_clock_idle_exit() cannot be called.
- *
- * Since this function can be preempted, we need to take some provisions to
- * announce all expected sys ticks that have passed.
- *
- */
-static void rtc_announce_set_next(void)
-{
-	u32_t rtc_now, rtc_elapsed, sys_elapsed;
-
-	/* Read the RTC counter one single time in the beginning, so that an
-	 * increase in the counter during this procedure leads to no race
-	 * conditions.
-	 */
-	rtc_now = RTC_COUNTER;
-
-	/* Calculate how many RTC ticks elapsed since the last sys tick. */
-	rtc_elapsed = (rtc_now - rtc_past) & RTC_MASK;
-
-	/* If no sys ticks have elapsed, there is no point in incrementing the
-	 * counters or announcing it.
-	 */
-	if (rtc_elapsed >= sys_clock_hw_cycles_per_tick()) {
-#ifdef CONFIG_TICKLESS_IDLE
-		/* Calculate how many sys ticks elapsed since the last sys tick
-		 * and notify the kernel if necessary.
-		 */
-		sys_elapsed = rtc_elapsed / sys_clock_hw_cycles_per_tick();
-
-		if (sys_elapsed > expected_sys_ticks) {
-			/* Never announce more sys ticks than the kernel asked
-			 * to be idle for. The remainder will be announced when
-			 * the RTC ISR runs after rtc_compare_set() is called
-			 * after the first announcement.
-			 */
-			sys_elapsed = expected_sys_ticks;
-		}
-#else
-		/* Never announce more than one sys tick if tickless idle is not
-		 * configured.
-		 */
-		sys_elapsed = 1;
-#endif /* CONFIG_TICKLESS_IDLE */
-
-		/* Store RTC_COUNTER floored to the last sys tick. This is
-		 * done, so that ISR can properly calculate that 1 sys tick
-		 * has passed.
-		 */
-		rtc_past = (rtc_past +
-				(sys_elapsed * sys_clock_hw_cycles_per_tick())
-			   ) & RTC_MASK;
-
-		_sys_idle_elapsed_ticks = sys_elapsed;
-		z_clock_announce(_sys_idle_elapsed_ticks);
-	}
-
-	/* Set the RTC to the next sys tick */
-	rtc_compare_set(rtc_past + sys_clock_hw_cycles_per_tick());
-}
-#endif
-
-#ifdef CONFIG_TICKLESS_IDLE
-/**
- * @brief Place system timer into idle state.
- *
- * Re-program the timer to enter into the idle state for the given number of
- * sys ticks, counted from the previous sys tick. The timer will fire in the
- * number of sys ticks supplied or the maximum number of sys ticks (converted
- * to RTC ticks) that can be programmed into the hardware.
- *
- * This will only be called from idle context, with IRQs disabled.
- *
- * A value of -1 will result in the maximum number of sys ticks.
- *
- * Example 1: Idle sleep is entered:
- *
- * sys tick timeline:       (1)    (2)    (3)    (4)    (5)    (6)
- * rtc tick timeline : 0----100----200----300----400----500----600
- *                               ******************
- *                              150
- *
- * a) The last sys tick was announced at 100
- * b) The idle context enters sleep at 150, between sys tick 1 and 2, with
- * sys_ticks = 3.
- * c) The RTC is programmed to fire at sys tick 1 + 3 = 4 (RTC tick 400)
- *
- * @return N/A
- */
-void _timer_idle_enter(s32_t sys_ticks)
-{
-#ifdef CONFIG_TICKLESS_KERNEL
-	if (sys_ticks != K_FOREVER) {
-		/* Need to reprograme timer if current program is smaller*/
-		if (sys_ticks > expected_sys_ticks) {
-			_set_time(sys_ticks);
-		}
-	} else {
-		expected_sys_ticks = 0;
-		/* Set time to largest possile RTC Tick*/
-		_set_time(_get_max_clock_time());
-	}
-#else
-	/* Restrict ticks to max supported by RTC without risking overflow*/
-	if ((sys_ticks < 0) ||
-		(sys_ticks > (RTC_HALF / sys_clock_hw_cycles_per_tick()))) {
-		sys_ticks = RTC_HALF / sys_clock_hw_cycles_per_tick();
-	}
-
-	expected_sys_ticks = sys_ticks;
-
-	/* If ticks is 0, the RTC interrupt handler will be set pending
-	 * immediately, meaning that we will not go to sleep.
-	 */
-	rtc_compare_set(rtc_past +
-			(sys_ticks * sys_clock_hw_cycles_per_tick()));
-#endif
+	return (a - b) & COUNTER_MAX;
 }
 
-
-#ifdef CONFIG_TICKLESS_KERNEL
-/*
- * Set RTC Counter Compare (CC) register to max value
- * and update the z_tick_get().
- */
-static inline void program_max_cycles(void)
+static void set_comparator(u32_t cyc)
 {
-	u32_t max_cycles = _get_max_clock_time();
-
-	z_tick_set(z_clock_uptime());
-	/* Update rtc_past to track rtc timer count*/
-	rtc_past = (z_tick_get() *
-			sys_clock_hw_cycles_per_tick()) & RTC_MASK;
-
-	/* Programe RTC compare register to generate interrupt*/
-	rtc_compare_set(rtc_past +
-			(max_cycles * sys_clock_hw_cycles_per_tick()));
-
+	nrf_rtc_cc_set(RTC, 0, cyc & COUNTER_MAX);
 }
 
-
-/**
- * @brief provides total systicks programmed.
- *
- * returns : total number of sys ticks programmed.
- */
-
-u32_t _get_program_time(void)
+static u32_t counter(void)
 {
-	return expected_sys_ticks;
+	return nrf_rtc_counter_get(RTC);
 }
 
-/**
- * @brief provides total systicks remaining since last programming of RTC.
- *
- * returns : total number of sys ticks remaining since last RTC programming.
- */
-
-u32_t _get_remaining_program_time(void)
-{
-
-	if (!expected_sys_ticks) {
-		return 0;
-	}
-
-	return (expected_sys_ticks - _get_elapsed_program_time());
-}
-
-/**
- * @brief provides total systicks passed since last programming of RTC.
- *
- * returns : total number of sys ticks passed since last RTC programming.
- */
-
-u32_t _get_elapsed_program_time(void)
-{
-	u32_t rtc_elapsed, rtc_past_copy;
-
-	if (!expected_sys_ticks) {
-		return 0;
-	}
-
-	/* Read rtc_past before RTC_COUNTER */
-	rtc_past_copy = rtc_past;
-
-	/* Make sure that compiler will not reverse access to RTC and
-	 * rtc_past.
-	 */
-	compiler_barrier();
-
-	rtc_elapsed = (RTC_COUNTER - rtc_past_copy) & RTC_MASK;
-
-	/* Convert number of Machine cycles to SYS_TICKS */
-	return (rtc_elapsed / sys_clock_hw_cycles_per_tick());
-}
-
-
-/**
- * @brief Sets interrupt for rtc compare value for systick time.
- *
- * This Function does following:-
- * 1. Updates expected_sys_ticks equal to time.
- * 2. Update kernel book keeping for time passed since device bootup.
- * 3. Calls routine to set rtc interrupt.
- */
-
-void _set_time(u32_t time)
-{
-	if (!time) {
-		expected_sys_ticks = 0;
-		return;
-	}
-
-	/* Update expected_sys_ticls to time to programe*/
-	expected_sys_ticks = time;
-	z_tick_set(z_clock_uptime());
-	/* Update rtc_past to track rtc timer count*/
-	rtc_past = (z_tick_get() * sys_clock_hw_cycles_per_tick()) & RTC_MASK;
-
-	expected_sys_ticks = expected_sys_ticks > _get_max_clock_time() ?
-				_get_max_clock_time() : expected_sys_ticks;
-
-	/* Programe RTC compare register to generate interrupt*/
-	rtc_compare_set(rtc_past +
-			(expected_sys_ticks * sys_clock_hw_cycles_per_tick()));
-
-}
-
-/**
- * @brief provides time remaining to reach rtc count overflow.
- *
- * This function returns how many sys RTC remaining for rtc to overflow.
- * This will be required when we will program RTC compare value to maximum
- * possible value.
- *
- * returns : difference between current systick and Maximum possible systick.
- */
-s32_t _get_max_clock_time(void)
-{
-	u32_t rtc_away, sys_away = 0;
-
-	/* Calculate time to program into RTC */
-	rtc_away = (RTC_MASK - RTC_COUNTER);
-	rtc_away = rtc_away > RTC_HALF ? RTC_HALF : rtc_away;
-
-	/* Convert RTC Ticks to SYS TICKS*/
-	if (rtc_away >= sys_clock_hw_cycles_per_tick()) {
-		sys_away = rtc_away / sys_clock_hw_cycles_per_tick();
-	}
-
-	return sys_away;
-}
-
-/**
- * @brief Enable sys Clock.
- *
- * This is used to program RTC clock to maximum Clock time in case Clock to
- * remain On.
- */
-void _enable_sys_clock(void)
-{
-	if (!expected_sys_ticks) {
-		/* Programe sys tick to Maximum possible value*/
-		program_max_cycles();
-	}
-}
-
-/**
- * @brief provides total systicks passed since device bootup.
- *
- * returns : total number of sys ticks passed since device bootup.
- */
-
-u64_t z_clock_uptime(void)
-{
-	u64_t elapsed;
-	u32_t rtc_elapsed, rtc_past_copy;
-
-	/* Read z_tick_get() and rtc_past before RTC_COUNTER */
-	elapsed = z_tick_get();
-	rtc_past_copy = rtc_past;
-
-	/* Make sure that compiler will not reverse access to RTC and
-	 * variables above.
-	 */
-	compiler_barrier();
-
-	rtc_elapsed = (RTC_COUNTER - rtc_past_copy) & RTC_MASK;
-	if (rtc_elapsed >= sys_clock_hw_cycles_per_tick()) {
-		/* Update total number of SYS_TICKS passed */
-		elapsed += (rtc_elapsed / sys_clock_hw_cycles_per_tick());
-	}
-
-	return elapsed;
-}
-#endif
-
-
-/**
- *
- * @brief Handling of tickless idle when interrupted
- *
- * The function will be called by _sys_power_save_idle_exit(), called from
- * _arch_isr_direct_pm() for 'direct' interrupts, or from _isr_wrapper for
- * regular ones, which is called on every IRQ handler if the device was
- * idle, and optionally called when a 'direct' IRQ handler executes if the
- * device was idle.
- *
- * Example 1: Idle sleep is interrupted before time:
- *
- * sys tick timeline:       (1)    (2)    (3)    (4)    (5)    (6)
- * rtc tick timeline : 0----100----200----300----400----500----600
- *                               **************!***
- *                              150           350
- *
- * Assume that _timer_idle_enter() is called at 150 (1) to sleep for 3
- * sys ticks. The last sys tick was announced at 100.
- *
- * On wakeup (non-RTC IRQ at 350):
- *
- * a) Notify how many sys ticks have passed, i.e., 350 - 150 / 100 = 2.
- * b) Schedule next sys tick at 400.
- *
- */
-void z_clock_idle_exit(void)
-{
-#ifdef CONFIG_TICKLESS_KERNEL
-	if (!expected_sys_ticks && _sys_clock_always_on) {
-		_set_time(_get_max_clock_time());
-	}
-#else
-	/* Clear the event flag and interrupt in case we woke up on the RTC
-	 * interrupt. No need to run the RTC ISR since everything that needs
-	 * to run in the ISR will be done in this call.
-	 */
-	RTC_CC_EVENT = 0;
-	NVIC_ClearPendingIRQ(NRF5_IRQ_RTC1_IRQn);
-
-	rtc_announce_set_next();
-
-	/* After exiting idle, the kernel no longer expects more than one sys
-	 * ticks to have passed when z_clock_announce() is called.
-	 */
-	expected_sys_ticks = 1;
-#endif
-}
-#endif /* CONFIG_TICKLESS_IDLE */
-
-/*
- * @brief Announces the number of sys ticks that have passed since the last
- * announcement, if any, and programs the RTC to trigger the interrupt on the
- * next sys tick.
- *
- * The ISR is set pending due to a regular sys tick and after exiting idle mode
- * as scheduled.
- *
- * Since this ISR can be preempted, we need to take some provisions to announce
- * all expected sys ticks that have passed.
- *
- * Consider the following example:
- *
- * sys tick timeline:       (1)    (2)    (3)    (4)    (5)    (6)
- * rtc tick timeline : 0----100----200----300----400----500----600
- *                                         !**********
- *                                                  450
- *
- * The last sys tick was anounced at 200, i.e, rtc_past = 200. The ISR is
- * executed at the next sys tick, i.e. 300. The following sys tick is due at
- * 400. However, the ISR is preempted for a number of sys ticks, until 450 in
- * this example. The ISR will then announce the number of sys ticks it was
- * delayed (2), and schedule the next sys tick (5) at 500.
+/* Note: this function has public linkage, and MUST have this
+ * particular name.  The platform architecture itself doesn't care,
+ * but there is a test (tests/kernel/arm_irq_vector_table) that needs
+ * to find it to it can set it in a custom vector table.  Should
+ * probably better abstract that at some point (e.g. query and reset
+ * it by pointer at runtime, maybe?) so we don't have this leaky
+ * symbol.
  */
 void rtc1_nrf5_isr(void *arg)
 {
-
 	ARG_UNUSED(arg);
-	RTC_CC_EVENT = 0;
+	RTC->EVENTS_COMPARE[0] = 0;
 
-#ifdef CONFIG_EXECUTION_BENCHMARKING
-	extern void read_timer_start_of_tick_handler(void);
-	read_timer_start_of_tick_handler();
-#endif
-	sys_trace_isr_enter();
+	k_spinlock_key_t key = k_spin_lock(&lock);
+	u32_t t = counter();
+	u32_t dticks = counter_sub(t, last_count) / CYC_PER_TICK;
 
-#ifdef CONFIG_TICKLESS_KERNEL
-	if (!expected_sys_ticks) {
-		if (_sys_clock_always_on) {
-			program_max_cycles();
+	last_count += dticks * CYC_PER_TICK;
+
+	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
+		u32_t next = last_count + CYC_PER_TICK;
+
+		if ((s32_t)(next - t) < MIN_DELAY) {
+			next += CYC_PER_TICK;
 		}
-		return;
+		set_comparator(next);
 	}
-	_sys_idle_elapsed_ticks = expected_sys_ticks;
-	/* Initialize expected sys tick,
-	 * It will be later updated based on next timeout.
-	 */
-	expected_sys_ticks = 0;
-	/* Anounce elapsed of _sys_idle_elapsed_ticks systicks*/
-	z_clock_announce(_sys_idle_elapsed_ticks);
 
-	/* z_clock_announce() could cause new programming */
-	if (!expected_sys_ticks && _sys_clock_always_on) {
-		program_max_cycles();
-	}
-#else
-	rtc_announce_set_next();
-#endif
-
-#ifdef CONFIG_EXECUTION_BENCHMARKING
-	extern void read_timer_end_of_tick_handler(void);
-	read_timer_end_of_tick_handler();
-#endif
-	sys_trace_isr_exit();
-
+	k_spin_unlock(&lock, key);
+	z_clock_announce(dticks);
 }
 
 int z_clock_driver_init(struct device *device)
@@ -523,87 +86,73 @@
 
 	clock_control_on(clock, (void *)CLOCK_CONTROL_NRF5_K32SRC);
 
-	rtc_past = 0;
-
-#ifdef CONFIG_TICKLESS_IDLE
-	expected_sys_ticks = 1;
-#endif /* CONFIG_TICKLESS_IDLE */
-
 	/* TODO: replace with counter driver to access RTC */
-	SYS_CLOCK_RTC->PRESCALER = 0;
-	nrf_rtc_cc_set(SYS_CLOCK_RTC, RTC_CC_IDX,
-		       sys_clock_hw_cycles_per_tick());
-	nrf_rtc_event_enable(SYS_CLOCK_RTC, RTC_EVTENSET_COMPARE0_Msk);
-	nrf_rtc_int_enable(SYS_CLOCK_RTC, RTC_INTENSET_COMPARE0_Msk);
+	nrf_rtc_prescaler_set(RTC, 0);
+	nrf_rtc_cc_set(RTC, 0, CYC_PER_TICK);
+	nrf_rtc_event_enable(RTC, RTC_EVTENSET_COMPARE0_Msk);
+	nrf_rtc_int_enable(RTC, RTC_INTENSET_COMPARE0_Msk);
 
 	/* Clear the event flag and possible pending interrupt */
-	RTC_CC_EVENT = 0;
+	nrf_rtc_event_clear(RTC, NRF_RTC_EVENT_COMPARE_0);
 	NVIC_ClearPendingIRQ(NRF5_IRQ_RTC1_IRQn);
 
 	IRQ_CONNECT(NRF5_IRQ_RTC1_IRQn, 1, rtc1_nrf5_isr, 0, 0);
 	irq_enable(NRF5_IRQ_RTC1_IRQn);
 
-	nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_CLEAR);
-	nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_START);
+	nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_CLEAR);
+	nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_START);
+
+	if (!IS_ENABLED(TICKLESS_KERNEL)) {
+		set_comparator(counter() + CYC_PER_TICK);
+	}
 
 	return 0;
 }
 
+void z_clock_set_timeout(s32_t ticks, bool idle)
+{
+	ARG_UNUSED(idle);
+
+#ifdef CONFIG_TICKLESS_KERNEL
+	ticks = (ticks == K_FOREVER) ? MAX_TICKS : ticks;
+	ticks = max(min(ticks - 1, (s32_t)MAX_TICKS), 0);
+
+	k_spinlock_key_t key = k_spin_lock(&lock);
+	u32_t cyc, t = counter();
+
+	/* Round up to next tick boundary */
+	cyc = ticks * CYC_PER_TICK + counter_sub(t, last_count);
+	cyc += (CYC_PER_TICK - 1);
+	cyc = (cyc / CYC_PER_TICK) * CYC_PER_TICK;
+	cyc += last_count;
+
+	if ((cyc - t) < MIN_DELAY) {
+		cyc += CYC_PER_TICK;
+	}
+
+	set_comparator(cyc);
+	k_spin_unlock(&lock, key);
+#endif
+}
+
+u32_t z_clock_elapsed(void)
+{
+	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
+		return 0;
+	}
+
+	k_spinlock_key_t key = k_spin_lock(&lock);
+	u32_t ret = counter_sub(counter(), last_count) / CYC_PER_TICK;
+
+	k_spin_unlock(&lock, key);
+	return ret;
+}
+
 u32_t _timer_cycle_get_32(void)
 {
-	u32_t ticked_cycles;
-	u32_t elapsed_cycles;
+	k_spinlock_key_t key = k_spin_lock(&lock);
+	u32_t ret = counter_sub(counter(), last_count) + last_count;
 
-	/* Number of timer cycles announced as ticks so far. */
-	ticked_cycles = z_tick_get() * sys_clock_hw_cycles_per_tick();
-
-	/* Make sure that compiler will not reverse access to RTC and
-	 * z_tick_get().
-	 */
-	compiler_barrier();
-
-	/* Number of timer cycles since last announced tick we know about.
-	 *
-	 * The value of RTC_COUNTER is not reset on tick, so it will
-	 * compensate potentialy missed update of z_tick_get()
-	 * which could have happen between the ticked_cycles calculation
-	 * and the code below.
-	 */
-	elapsed_cycles = (RTC_COUNTER - ticked_cycles) & RTC_MASK;
-
-	return ticked_cycles + elapsed_cycles;
+	k_spin_unlock(&lock, key);
+	return ret;
 }
-
-#ifdef CONFIG_SYSTEM_CLOCK_DISABLE
-/**
- *
- * @brief Stop announcing sys ticks into the kernel
- *
- * This routine disables the RTC1 so that timer interrupts are no
- * longer delivered.
- *
- * @return N/A
- */
-void sys_clock_disable(void)
-{
-	unsigned int key;
-
-	key = irq_lock();
-
-	irq_disable(NRF5_IRQ_RTC1_IRQn);
-
-	nrf_rtc_event_disable(SYS_CLOCK_RTC, RTC_EVTENCLR_COMPARE0_Msk);
-	nrf_rtc_int_disable(SYS_CLOCK_RTC, RTC_INTENCLR_COMPARE0_Msk);
-
-
-	nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_STOP);
-	nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_CLEAR);
-
-	irq_unlock(key);
-
-	/* TODO: turn off (release) 32 KHz clock source.
-	 * Turning off of 32 KHz clock source is not implemented in clock
-	 * driver.
-	 */
-}
-#endif /* CONFIG_SYSTEM_CLOCK_DISABLE */