#include <linux/module.h>
 #include <linux/timex.h>
 
+#include <clocksource/arm_arch_timer.h>
+
+#define USECS_TO_CYCLES(time_usecs)                    \
+       xloops_to_cycles((time_usecs) * 0x10C7UL)
+
+static inline unsigned long xloops_to_cycles(unsigned long xloops)
+{
+       return (xloops * loops_per_jiffy * HZ) >> 32;
+}
+
 void __delay(unsigned long cycles)
 {
        cycles_t start = get_cycles();
 
+       if (arch_timer_evtstrm_available()) {
+               const cycles_t timer_evt_period =
+                       USECS_TO_CYCLES(ARCH_TIMER_EVT_STREAM_PERIOD_US);
+
+               while ((get_cycles() - start + timer_evt_period) < cycles)
+                       wfe();
+       }
+
        while ((get_cycles() - start) < cycles)
                cpu_relax();
 }
 
 inline void __const_udelay(unsigned long xloops)
 {
-       unsigned long loops;
-
-       loops = xloops * loops_per_jiffy * HZ;
-       __delay(loops >> 32);
+       __delay(xloops_to_cycles(xloops));
 }
 EXPORT_SYMBOL(__const_udelay);
 
 
 #define ARCH_TIMER_USR_VT_ACCESS_EN    (1 << 8) /* virtual timer registers */
 #define ARCH_TIMER_USR_PT_ACCESS_EN    (1 << 9) /* physical timer registers */
 
-#define ARCH_TIMER_EVT_STREAM_FREQ     10000   /* 100us */
+#define ARCH_TIMER_EVT_STREAM_PERIOD_US        100
+#define ARCH_TIMER_EVT_STREAM_FREQ                             \
+       (USEC_PER_SEC / ARCH_TIMER_EVT_STREAM_PERIOD_US)
 
 struct arch_timer_kvm_info {
        struct timecounter timecounter;