Changeset 615 for GPL/branches/uniaud32-next/lib32/timer.c
- Timestamp:
- Jan 1, 2021, 5:31:48 AM (5 years ago)
- Location:
- GPL/branches/uniaud32-next
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
GPL/branches/uniaud32-next/lib32/timer.c
r445 r615 30 30 #include <asm/io.h> 31 31 #include <linux/time.h> 32 #include <linux/math64.h> 33 #include <linux/clocksource.h> 32 34 33 35 #define LINUX … … 140 142 //****************************************************************************** 141 143 //****************************************************************************** 144 145 /** 146 * ns_to_timespec - Convert nanoseconds to timespec 147 * @nsec: the nanoseconds value to be converted 148 * 149 * Returns the timespec representation of the nsec parameter. 150 */ 151 struct timespec ns_to_timespec(const s64 nsec) 152 { 153 struct timespec ts; 154 s32 rem; 155 156 if (!nsec) { 157 ts.tv_sec = 0; 158 ts.tv_nsec = 0; 159 return ts; 160 } 161 162 ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem); 163 if (unlikely(rem < 0)) { 164 ts.tv_sec--; 165 rem += NSEC_PER_SEC; 166 } 167 ts.tv_nsec = rem; 168 169 return ts; 170 } 171 172 173 //****************************************************************************** 174 //****************************************************************************** 175 176 void timecounter_init(struct timecounter *tc, 177 const struct cyclecounter *cc, 178 u64 start_tstamp) 179 { 180 tc->cc = cc; 181 tc->cycle_last = cc->read(cc); 182 tc->nsec = start_tstamp; 183 } 184 185 /** 186 * timecounter_read_delta - get nanoseconds since last call of this function 187 * @tc: Pointer to time counter 188 * 189 * When the underlying cycle counter runs over, this will be handled 190 * correctly as long as it does not run over more than once between 191 * calls. 192 * 193 * The first call to this function for a new time counter initializes 194 * the time tracking and returns an undefined result. 195 */ 196 static u64 timecounter_read_delta(struct timecounter *tc) 197 { 198 cycle_t cycle_now, cycle_delta; 199 u64 ns_offset; 200 201 /* read cycle counter: */ 202 cycle_now = tc->cc->read(tc->cc); 203 204 /* calculate the delta since the last timecounter_read_delta(): */ 205 cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask; 206 207 /* convert to nanoseconds: */ 208 ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta); 209 210 /* update time stamp of timecounter_read_delta() call: */ 211 tc->cycle_last = cycle_now; 212 213 return ns_offset; 214 } 215 216 u64 timecounter_read(struct timecounter *tc) 217 { 218 u64 nsec; 219 220 /* increment time by nanoseconds since last call */ 221 nsec = timecounter_read_delta(tc); 222 nsec += tc->nsec; 223 tc->nsec = nsec; 224 225 return nsec; 226 } 227 228 /** 229 * set_normalized_timespec - set timespec sec and nsec parts and normalize 230 * 231 * @ts: pointer to timespec variable to be set 232 * @sec: seconds to set 233 * @nsec: nanoseconds to set 234 * 235 * Set seconds and nanoseconds field of a timespec variable and 236 * normalize to the timespec storage format 237 * 238 * Note: The tv_nsec part is always in the range of 239 * 0 <= tv_nsec < NSEC_PER_SEC 240 * For negative values only the tv_sec field is negative ! 241 */ 242 void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec) 243 { 244 while (nsec >= NSEC_PER_SEC) { 245 /* 246 * The following asm() prevents the compiler from 247 * optimising this loop into a modulo operation. See 248 * also __iter_div_u64_rem() in include/linux/time.h 249 */ 250 // asm("" : "+rm"(nsec)); 251 nsec -= NSEC_PER_SEC; 252 ++sec; 253 } 254 while (nsec < 0) { 255 // asm("" : "+rm"(nsec)); 256 nsec += NSEC_PER_SEC; 257 --sec; 258 } 259 ts->tv_sec = sec; 260 ts->tv_nsec = nsec; 261 }
Note:
See TracChangeset
for help on using the changeset viewer.