18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. 38c2ecf20Sopenharmony_ci */ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#ifndef _ASM_SPARC_VVAR_DATA_H 68c2ecf20Sopenharmony_ci#define _ASM_SPARC_VVAR_DATA_H 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <asm/clocksource.h> 98c2ecf20Sopenharmony_ci#include <asm/processor.h> 108c2ecf20Sopenharmony_ci#include <asm/barrier.h> 118c2ecf20Sopenharmony_ci#include <linux/time.h> 128c2ecf20Sopenharmony_ci#include <linux/types.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistruct vvar_data { 158c2ecf20Sopenharmony_ci unsigned int seq; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci int vclock_mode; 188c2ecf20Sopenharmony_ci struct { /* extract of a clocksource struct */ 198c2ecf20Sopenharmony_ci u64 cycle_last; 208c2ecf20Sopenharmony_ci u64 mask; 218c2ecf20Sopenharmony_ci int mult; 228c2ecf20Sopenharmony_ci int shift; 238c2ecf20Sopenharmony_ci } clock; 248c2ecf20Sopenharmony_ci /* open coded 'struct timespec' */ 258c2ecf20Sopenharmony_ci u64 wall_time_sec; 268c2ecf20Sopenharmony_ci u64 wall_time_snsec; 278c2ecf20Sopenharmony_ci u64 monotonic_time_snsec; 288c2ecf20Sopenharmony_ci u64 monotonic_time_sec; 298c2ecf20Sopenharmony_ci u64 monotonic_time_coarse_sec; 308c2ecf20Sopenharmony_ci u64 monotonic_time_coarse_nsec; 318c2ecf20Sopenharmony_ci u64 wall_time_coarse_sec; 328c2ecf20Sopenharmony_ci u64 wall_time_coarse_nsec; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci int tz_minuteswest; 358c2ecf20Sopenharmony_ci int tz_dsttime; 368c2ecf20Sopenharmony_ci}; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciextern struct vvar_data *vvar_data; 398c2ecf20Sopenharmony_ciextern int vdso_fix_stick; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic inline unsigned int vvar_read_begin(const struct vvar_data *s) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci unsigned int ret; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cirepeat: 468c2ecf20Sopenharmony_ci ret = READ_ONCE(s->seq); 478c2ecf20Sopenharmony_ci if (unlikely(ret & 1)) { 488c2ecf20Sopenharmony_ci cpu_relax(); 498c2ecf20Sopenharmony_ci goto repeat; 508c2ecf20Sopenharmony_ci } 518c2ecf20Sopenharmony_ci smp_rmb(); /* Finish all reads before we return seq */ 528c2ecf20Sopenharmony_ci return ret; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic inline int vvar_read_retry(const struct vvar_data *s, 568c2ecf20Sopenharmony_ci unsigned int start) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci smp_rmb(); /* Finish all reads before checking the value of seq */ 598c2ecf20Sopenharmony_ci return unlikely(s->seq != start); 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic inline void vvar_write_begin(struct vvar_data *s) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci ++s->seq; 658c2ecf20Sopenharmony_ci smp_wmb(); /* Makes sure that increment of seq is reflected */ 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic inline void vvar_write_end(struct vvar_data *s) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci smp_wmb(); /* Makes the value of seq current before we increment */ 718c2ecf20Sopenharmony_ci ++s->seq; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#endif /* _ASM_SPARC_VVAR_DATA_H */ 76