^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * S390 version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright IBM Corp. 1999
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Derived from "include/asm-i386/timex.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1992, Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #ifndef _ASM_S390_TIMEX_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define _ASM_S390_TIMEX_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/preempt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/lowcore.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* The value of the TOD clock for 1.1.1970. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) extern u64 clock_comparator_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* Inline functions for clock register access. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static inline int set_tod_clock(__u64 time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) " sck %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) " ipm %0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) " srl %0,28\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) : "=d" (cc) : "Q" (time) : "cc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static inline int store_tod_clock(__u64 *time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) " stck %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) " ipm %0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) " srl %0,28\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) : "=d" (cc), "=Q" (*time) : : "cc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static inline void set_clock_comparator(__u64 time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) asm volatile("sckc %0" : : "Q" (time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void clock_comparator_work(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void __init time_early_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) extern unsigned char ptff_function_mask[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Function codes for the ptff instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PTFF_QAF 0x00 /* query available functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PTFF_QTO 0x01 /* query tod offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PTFF_QSI 0x02 /* query steering information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define PTFF_QUI 0x04 /* query UTC information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PTFF_ATO 0x40 /* adjust tod offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define PTFF_STO 0x41 /* set tod offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PTFF_SFS 0x42 /* set fine steering rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PTFF_SGS 0x43 /* set gross steering rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Query TOD offset result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct ptff_qto {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned long long physical_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned long long tod_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned long long logical_tod_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned long long tod_epoch_difference;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static inline int ptff_query(unsigned int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ptr = ptff_function_mask + (nr >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return (*ptr & (0x80 >> (nr & 7))) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Query UTC information result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct ptff_qui {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int tm : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int ts : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int : 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int pad_0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long leap_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) short old_leap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) short new_leap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned int pad_0x14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned long prt[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long cst[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned int skew;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned int pad_0x5c[41];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * ptff - Perform timing facility function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @ptff_block: Pointer to ptff parameter block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @len: Length of parameter block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @func: Function code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Returns: Condition code (0 on success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ptff(ptff_block, len, func) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct addrtype { char _[len]; }; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) register unsigned int reg0 asm("0") = func; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) register unsigned long reg1 asm("1") = (unsigned long) (ptff_block);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int rc; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) asm volatile( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) " .word 0x0104\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) " ipm %0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) " srl %0,28\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) : "=d" (rc), "+m" (*(struct addrtype *) reg1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) : "d" (reg0), "d" (reg1) : "cc"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) rc; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static inline unsigned long long local_tick_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned long long old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) old = S390_lowcore.clock_comparator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) S390_lowcore.clock_comparator = clock_comparator_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) set_clock_comparator(S390_lowcore.clock_comparator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static inline void local_tick_enable(unsigned long long comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) S390_lowcore.clock_comparator = comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) set_clock_comparator(S390_lowcore.clock_comparator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define STORE_CLOCK_EXT_SIZE 16 /* stcke writes 16 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) typedef unsigned long long cycles_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static inline void get_tod_clock_ext(char *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) typedef struct { char _[STORE_CLOCK_EXT_SIZE]; } addrtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) asm volatile("stcke %0" : "=Q" (*(addrtype *) clk) : : "cc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static inline unsigned long long get_tod_clock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) char clk[STORE_CLOCK_EXT_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) get_tod_clock_ext(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return *((unsigned long long *)&clk[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static inline unsigned long long get_tod_clock_fast(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned long long clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) asm volatile("stckf %0" : "=Q" (clk) : : "cc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return get_tod_clock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static inline cycles_t get_cycles(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return (cycles_t) get_tod_clock() >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int get_phys_clock(unsigned long *clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) void init_cpu_timer(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) extern unsigned char tod_clock_base[16] __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * get_clock_monotonic - returns current time in clock rate units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * The clock and tod_clock_base get changed via stop_machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Therefore preemption must be disabled, otherwise the returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * value is not guaranteed to be monotonic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static inline unsigned long long get_tod_clock_monotonic(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) unsigned long long tod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) preempt_disable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) tod = get_tod_clock() - *(unsigned long long *) &tod_clock_base[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) preempt_enable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return tod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * tod_to_ns - convert a TOD format value to nanoseconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @todval: to be converted TOD format value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * Returns: number of nanoseconds that correspond to the TOD format value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Converting a 64 Bit TOD format value to nanoseconds means that the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * must be divided by 4.096. In order to achieve that we multiply with 125
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * and divide by 512:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * ns = (todval * 125) >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * In order to avoid an overflow with the multiplication we can rewrite this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * With a split todval == 2^9 * th + tl (th upper 55 bits, tl lower 9 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * we end up with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * ns = ((2^9 * th + tl) * 125 ) >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * -> ns = (th * 125) + ((tl * 125) >> 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static inline unsigned long long tod_to_ns(unsigned long long todval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return ((todval >> 9) * 125) + (((todval & 0x1ff) * 125) >> 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * tod_after - compare two 64 bit TOD values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * @a: first 64 bit TOD timestamp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * @b: second 64 bit TOD timestamp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * Returns: true if a is later than b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static inline int tod_after(unsigned long long a, unsigned long long b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (MACHINE_HAS_SCC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return (long long) a > (long long) b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return a > b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * tod_after_eq - compare two 64 bit TOD values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @a: first 64 bit TOD timestamp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @b: second 64 bit TOD timestamp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Returns: true if a is later than b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static inline int tod_after_eq(unsigned long long a, unsigned long long b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (MACHINE_HAS_SCC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return (long long) a >= (long long) b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return a >= b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #endif