Ignore:
Timestamp:
Jan 1, 2021, 5:31:48 AM (5 years ago)
Author:
Paul Smedley
Message:

Add source for uniaud32 based on code from linux kernel 5.4.86

Location:
GPL/branches/uniaud32-next
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • GPL/branches/uniaud32-next/lib32/timer.c

    r445 r615  
    3030#include <asm/io.h>
    3131#include <linux/time.h>
     32#include <linux/math64.h>
     33#include <linux/clocksource.h>
    3234
    3335#define LINUX
     
    140142//******************************************************************************
    141143//******************************************************************************
     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 */
     151struct 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
     176void 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 */
     196static 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
     216u64 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 */
     242void 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.