~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/kernel/time.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arm/kernel/time.c (Version linux-6.11-rc3) and /arch/ppc/kernel/time.c (Version linux-2.6.0)


  1 // SPDX-License-Identifier: GPL-2.0-only       << 
  2 /*                                                  1 /*
  3  *  linux/arch/arm/kernel/time.c               !!   2  * Common time routines among all ppc machines.
  4  *                                                  3  *
  5  *  Copyright (C) 1991, 1992, 1995  Linus Torv !!   4  * Written by Cort Dougan (cort@cs.nmt.edu) to merge
  6  *  Modifications for ARM (C) 1994-2001 Russel !!   5  * Paul Mackerras' version and mine for PReP and Pmac.
                                                   >>   6  * MPC8xx/MBX changes by Dan Malek (dmalek@jlc.net).
  7  *                                                  7  *
  8  *  This file contains the ARM-specific time h !!   8  * First round of bugfixes by Gabriel Paubert (paubert@iram.es)
  9  *  reading the RTC at bootup, etc...          !!   9  * to make clock more stable (2.4.0-test5). The only thing
                                                   >>  10  * that this code assumes is that the timebases have been synchronized
                                                   >>  11  * by firmware on SMP and are never stopped (never do sleep
                                                   >>  12  * on SMP then, nap and doze are OK).
                                                   >>  13  *
                                                   >>  14  * TODO (not necessarily in this file):
                                                   >>  15  * - improve precision and reproducibility of timebase frequency
                                                   >>  16  * measurement at boot time.
                                                   >>  17  * - get rid of xtime_lock for gettimeofday (generic kernel problem
                                                   >>  18  * to be implemented on all architectures for SMP scalability and
                                                   >>  19  * eventually implementing gettimeofday without entering the kernel).
                                                   >>  20  * - put all time/clock related variables in a single structure
                                                   >>  21  * to minimize number of cache lines touched by gettimeofday()
                                                   >>  22  * - for astronomical applications: add a new function to get
                                                   >>  23  * non ambiguous timestamps even around leap seconds. This needs
                                                   >>  24  * a new timestamp format and a good name.
                                                   >>  25  *
                                                   >>  26  *
                                                   >>  27  * The following comment is partially obsolete (at least the long wait
                                                   >>  28  * is no more a valid reason):
                                                   >>  29  * Since the MPC8xx has a programmable interrupt timer, I decided to
                                                   >>  30  * use that rather than the decrementer.  Two reasons: 1.) the clock
                                                   >>  31  * frequency is low, causing 2.) a long wait in the timer interrupt
                                                   >>  32  *              while ((d = get_dec()) == dval)
                                                   >>  33  * loop.  The MPC8xx can be driven from a variety of input clocks,
                                                   >>  34  * so a number of assumptions have been made here because the kernel
                                                   >>  35  * parameter HZ is a constant.  We assume (correctly, today :-) that
                                                   >>  36  * the MPC8xx on the MBX board is driven from a 32.768 kHz crystal.
                                                   >>  37  * This is then divided by 4, providing a 8192 Hz clock into the PIT.
                                                   >>  38  * Since it is not possible to get a nice 100 Hz clock out of this, without
                                                   >>  39  * creating a software PLL, I have set HZ to 128.  -- Dan
                                                   >>  40  *
                                                   >>  41  * 1997-09-10  Updated NTP code according to technical memorandum Jan '96
                                                   >>  42  *             "A Kernel Model for Precision Timekeeping" by Dave Mills
 10  */                                                43  */
 11 #include <linux/clockchips.h>                  !!  44 
 12 #include <linux/clocksource.h>                 !!  45 #include <linux/config.h>
 13 #include <linux/errno.h>                           46 #include <linux/errno.h>
 14 #include <linux/export.h>                      << 
 15 #include <linux/init.h>                        << 
 16 #include <linux/interrupt.h>                   << 
 17 #include <linux/irq.h>                         << 
 18 #include <linux/kernel.h>                      << 
 19 #include <linux/of_clk.h>                      << 
 20 #include <linux/profile.h>                     << 
 21 #include <linux/sched.h>                           47 #include <linux/sched.h>
 22 #include <linux/sched_clock.h>                 !!  48 #include <linux/kernel.h>
 23 #include <linux/smp.h>                         !!  49 #include <linux/param.h>
 24 #include <linux/time.h>                        !!  50 #include <linux/string.h>
                                                   >>  51 #include <linux/mm.h>
                                                   >>  52 #include <linux/module.h>
                                                   >>  53 #include <linux/interrupt.h>
 25 #include <linux/timex.h>                           54 #include <linux/timex.h>
 26 #include <linux/timer.h>                       !!  55 #include <linux/kernel_stat.h>
                                                   >>  56 #include <linux/mc146818rtc.h>
                                                   >>  57 #include <linux/time.h>
                                                   >>  58 #include <linux/init.h>
                                                   >>  59 
                                                   >>  60 #include <asm/segment.h>
                                                   >>  61 #include <asm/io.h>
                                                   >>  62 #include <asm/nvram.h>
                                                   >>  63 #include <asm/cache.h>
                                                   >>  64 #include <asm/8xx_immap.h>
                                                   >>  65 #include <asm/machdep.h>
                                                   >>  66 
                                                   >>  67 #include <asm/time.h>
                                                   >>  68 
                                                   >>  69 /* XXX false sharing with below? */
                                                   >>  70 u64 jiffies_64 = INITIAL_JIFFIES;
                                                   >>  71 
                                                   >>  72 EXPORT_SYMBOL(jiffies_64);
                                                   >>  73 
                                                   >>  74 unsigned long disarm_decr[NR_CPUS];
                                                   >>  75 
                                                   >>  76 extern struct timezone sys_tz;
                                                   >>  77 
                                                   >>  78 /* keep track of when we need to update the rtc */
                                                   >>  79 time_t last_rtc_update;
                                                   >>  80 
                                                   >>  81 /* The decrementer counts down by 128 every 128ns on a 601. */
                                                   >>  82 #define DECREMENTER_COUNT_601   (1000000000 / HZ)
                                                   >>  83 
                                                   >>  84 unsigned tb_ticks_per_jiffy;
                                                   >>  85 unsigned tb_to_us;
                                                   >>  86 unsigned tb_last_stamp;
                                                   >>  87 unsigned long tb_to_ns_scale;
                                                   >>  88 
                                                   >>  89 extern unsigned long wall_jiffies;
                                                   >>  90 
                                                   >>  91 static long time_offset;
                                                   >>  92 
                                                   >>  93 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 27                                                    94 
 28 #include <asm/mach/arch.h>                     << 
 29 #include <asm/mach/time.h>                     << 
 30 #include <asm/stacktrace.h>                    << 
 31 #include <asm/thread_info.h>                   << 
 32                                                << 
 33 #if defined(CONFIG_RTC_DRV_CMOS) || defined(CO << 
 34     defined(CONFIG_NVRAM) || defined(CONFIG_NV << 
 35 /* this needs a better home */                 << 
 36 DEFINE_SPINLOCK(rtc_lock);                     << 
 37 EXPORT_SYMBOL(rtc_lock);                           95 EXPORT_SYMBOL(rtc_lock);
 38 #endif  /* pc-style 'CMOS' RTC support */      << 
 39                                                    96 
 40 /* change this if you have some constant time  !!  97 /* Timer interrupt helper function */
 41 #define USECS_PER_JIFFY (1000000/HZ)           !!  98 static inline int tb_delta(unsigned *jiffy_stamp) {
                                                   >>  99         int delta;
                                                   >> 100         if (__USE_RTC()) {
                                                   >> 101                 delta = get_rtcl();
                                                   >> 102                 if (delta < *jiffy_stamp) *jiffy_stamp -= 1000000000;
                                                   >> 103                 delta -= *jiffy_stamp;
                                                   >> 104         } else {
                                                   >> 105                 delta = get_tbl() - *jiffy_stamp;
                                                   >> 106         }
                                                   >> 107         return delta;
                                                   >> 108 }
 42                                                   109 
 43 #ifdef CONFIG_SMP                              !! 110 extern unsigned long prof_cpu_mask;
 44 unsigned long profile_pc(struct pt_regs *regs) !! 111 extern unsigned int * prof_buffer;
                                                   >> 112 extern unsigned long prof_len;
                                                   >> 113 extern unsigned long prof_shift;
                                                   >> 114 extern char _stext;
                                                   >> 115 
                                                   >> 116 static inline void ppc_do_profile (unsigned long nip)
 45 {                                                 117 {
 46         struct stackframe frame;               !! 118         if (!prof_buffer)
                                                   >> 119                 return;
 47                                                   120 
 48         if (!in_lock_functions(regs->ARM_pc))  !! 121         /*
 49                 return regs->ARM_pc;           !! 122          * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
                                                   >> 123          * (default is all CPUs.)
                                                   >> 124          */
                                                   >> 125         if (!((1<<smp_processor_id()) & prof_cpu_mask))
                                                   >> 126                 return;
                                                   >> 127 
                                                   >> 128         nip -= (unsigned long) &_stext;
                                                   >> 129         nip >>= prof_shift;
                                                   >> 130         /*
                                                   >> 131          * Don't ignore out-of-bounds EIP values silently,
                                                   >> 132          * put them into the last histogram slot, so if
                                                   >> 133          * present, they will show up as a sharp peak.
                                                   >> 134          */
                                                   >> 135         if (nip > prof_len-1)
                                                   >> 136                 nip = prof_len-1;
                                                   >> 137         atomic_inc((atomic_t *)&prof_buffer[nip]);
                                                   >> 138 }
 50                                                   139 
 51         arm_get_current_stackframe(regs, &fram !! 140 /*
 52         do {                                   !! 141  * timer_interrupt - gets called when the decrementer overflows,
 53                 int ret = unwind_frame(&frame) !! 142  * with interrupts disabled.
 54                 if (ret < 0)                   !! 143  * We set it up to overflow again in 1/HZ seconds.
 55                         return 0;              !! 144  */
 56         } while (in_lock_functions(frame.pc)); !! 145 void timer_interrupt(struct pt_regs * regs)
                                                   >> 146 {
                                                   >> 147         int next_dec;
                                                   >> 148         unsigned long cpu = smp_processor_id();
                                                   >> 149         unsigned jiffy_stamp = last_jiffy_stamp(cpu);
                                                   >> 150         extern void do_IRQ(struct pt_regs *);
                                                   >> 151 
                                                   >> 152         if (atomic_read(&ppc_n_lost_interrupts) != 0)
                                                   >> 153                 do_IRQ(regs);
                                                   >> 154 
                                                   >> 155         irq_enter();
                                                   >> 156 
                                                   >> 157         while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) {
                                                   >> 158                 jiffy_stamp += tb_ticks_per_jiffy;
                                                   >> 159                 if (!user_mode(regs))
                                                   >> 160                         ppc_do_profile(instruction_pointer(regs));
                                                   >> 161                 if (smp_processor_id())
                                                   >> 162                         continue;
                                                   >> 163 
                                                   >> 164                 /* We are in an interrupt, no need to save/restore flags */
                                                   >> 165                 write_seqlock(&xtime_lock);
                                                   >> 166                 tb_last_stamp = jiffy_stamp;
                                                   >> 167                 do_timer(regs);
                                                   >> 168 
                                                   >> 169                 /*
                                                   >> 170                  * update the rtc when needed, this should be performed on the
                                                   >> 171                  * right fraction of a second. Half or full second ?
                                                   >> 172                  * Full second works on mk48t59 clocks, others need testing.
                                                   >> 173                  * Note that this update is basically only used through
                                                   >> 174                  * the adjtimex system calls. Setting the HW clock in
                                                   >> 175                  * any other way is a /dev/rtc and userland business.
                                                   >> 176                  * This is still wrong by -0.5/+1.5 jiffies because of the
                                                   >> 177                  * timer interrupt resolution and possible delay, but here we
                                                   >> 178                  * hit a quantization limit which can only be solved by higher
                                                   >> 179                  * resolution timers and decoupling time management from timer
                                                   >> 180                  * interrupts. This is also wrong on the clocks
                                                   >> 181                  * which require being written at the half second boundary.
                                                   >> 182                  * We should have an rtc call that only sets the minutes and
                                                   >> 183                  * seconds like on Intel to avoid problems with non UTC clocks.
                                                   >> 184                  */
                                                   >> 185                 if ( ppc_md.set_rtc_time && (time_status & STA_UNSYNC) == 0 &&
                                                   >> 186                      xtime.tv_sec - last_rtc_update >= 659 &&
                                                   >> 187                      abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ &&
                                                   >> 188                      jiffies - wall_jiffies == 1) {
                                                   >> 189                         if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
                                                   >> 190                                 last_rtc_update = xtime.tv_sec+1;
                                                   >> 191                         else
                                                   >> 192                                 /* Try again one minute later */
                                                   >> 193                                 last_rtc_update += 60;
                                                   >> 194                 }
                                                   >> 195                 write_sequnlock(&xtime_lock);
                                                   >> 196         }
                                                   >> 197         if ( !disarm_decr[smp_processor_id()] )
                                                   >> 198                 set_dec(next_dec);
                                                   >> 199         last_jiffy_stamp(cpu) = jiffy_stamp;
                                                   >> 200 
                                                   >> 201 #ifdef CONFIG_SMP
                                                   >> 202         smp_local_timer_interrupt(regs);
                                                   >> 203 #endif /* CONFIG_SMP */
                                                   >> 204 
                                                   >> 205         if (ppc_md.heartbeat && !ppc_md.heartbeat_count--)
                                                   >> 206                 ppc_md.heartbeat();
 57                                                   207 
 58         return frame.pc;                       !! 208         irq_exit();
 59 }                                                 209 }
 60 EXPORT_SYMBOL(profile_pc);                     << 
 61 #endif                                         << 
 62                                                   210 
 63 static void dummy_clock_access(struct timespec !! 211 /*
                                                   >> 212  * This version of gettimeofday has microsecond resolution.
                                                   >> 213  */
                                                   >> 214 void do_gettimeofday(struct timeval *tv)
 64 {                                                 215 {
 65         ts->tv_sec = 0;                        !! 216         unsigned long flags;
 66         ts->tv_nsec = 0;                       !! 217         unsigned long seq;
                                                   >> 218         unsigned delta, lost_ticks, usec, sec;
                                                   >> 219 
                                                   >> 220         do {
                                                   >> 221                 seq = read_seqbegin_irqsave(&xtime_lock, flags);
                                                   >> 222                 sec = xtime.tv_sec;
                                                   >> 223                 usec = (xtime.tv_nsec / 1000);
                                                   >> 224                 delta = tb_ticks_since(tb_last_stamp);
                                                   >> 225 #ifdef CONFIG_SMP
                                                   >> 226                 /* As long as timebases are not in sync, gettimeofday can only
                                                   >> 227                  * have jiffy resolution on SMP.
                                                   >> 228                  */
                                                   >> 229                 if (!smp_tb_synchronized)
                                                   >> 230                         delta = 0;
                                                   >> 231 #endif /* CONFIG_SMP */
                                                   >> 232                 lost_ticks = jiffies - wall_jiffies;
                                                   >> 233         } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
                                                   >> 234 
                                                   >> 235         usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta);
                                                   >> 236         while (usec >= 1000000) {
                                                   >> 237                 sec++;
                                                   >> 238                 usec -= 1000000;
                                                   >> 239         }
                                                   >> 240         tv->tv_sec = sec;
                                                   >> 241         tv->tv_usec = usec;
 67 }                                                 242 }
 68                                                   243 
 69 static clock_access_fn __read_persistent_clock !! 244 EXPORT_SYMBOL(do_gettimeofday);
 70                                                   245 
 71 void read_persistent_clock64(struct timespec64 !! 246 int do_settimeofday(struct timespec *tv)
 72 {                                                 247 {
 73         __read_persistent_clock(ts);           !! 248         time_t wtm_sec, new_sec = tv->tv_sec;
                                                   >> 249         long wtm_nsec, new_nsec = tv->tv_nsec;
                                                   >> 250         unsigned long flags;
                                                   >> 251         int tb_delta;
                                                   >> 252 
                                                   >> 253         if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
                                                   >> 254                 return -EINVAL;
                                                   >> 255 
                                                   >> 256         write_seqlock_irqsave(&xtime_lock, flags);
                                                   >> 257         /* Updating the RTC is not the job of this code. If the time is
                                                   >> 258          * stepped under NTP, the RTC will be update after STA_UNSYNC
                                                   >> 259          * is cleared. Tool like clock/hwclock either copy the RTC
                                                   >> 260          * to the system time, in which case there is no point in writing
                                                   >> 261          * to the RTC again, or write to the RTC but then they don't call
                                                   >> 262          * settimeofday to perform this operation. Note also that
                                                   >> 263          * we don't touch the decrementer since:
                                                   >> 264          * a) it would lose timer interrupt synchronization on SMP
                                                   >> 265          * (if it is working one day)
                                                   >> 266          * b) it could make one jiffy spuriously shorter or longer
                                                   >> 267          * which would introduce another source of uncertainty potentially
                                                   >> 268          * harmful to relatively short timers.
                                                   >> 269          */
                                                   >> 270 
                                                   >> 271         /* This works perfectly on SMP only if the tb are in sync but
                                                   >> 272          * guarantees an error < 1 jiffy even if they are off by eons,
                                                   >> 273          * still reasonable when gettimeofday resolution is 1 jiffy.
                                                   >> 274          */
                                                   >> 275         tb_delta = tb_ticks_since(last_jiffy_stamp(smp_processor_id()));
                                                   >> 276         tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
                                                   >> 277 
                                                   >> 278         new_nsec -= 1000 * mulhwu(tb_to_us, tb_delta);
                                                   >> 279 
                                                   >> 280         wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
                                                   >> 281         wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
                                                   >> 282 
                                                   >> 283         set_normalized_timespec(&xtime, new_sec, new_nsec);
                                                   >> 284         set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
                                                   >> 285 
                                                   >> 286         /* In case of a large backwards jump in time with NTP, we want the
                                                   >> 287          * clock to be updated as soon as the PLL is again in lock.
                                                   >> 288          */
                                                   >> 289         last_rtc_update = new_sec - 658;
                                                   >> 290 
                                                   >> 291         time_adjust = 0;                /* stop active adjtime() */
                                                   >> 292         time_status |= STA_UNSYNC;
                                                   >> 293         time_state = TIME_ERROR;        /* p. 24, (a) */
                                                   >> 294         time_maxerror = NTP_PHASE_LIMIT;
                                                   >> 295         time_esterror = NTP_PHASE_LIMIT;
                                                   >> 296         write_sequnlock_irqrestore(&xtime_lock, flags);
                                                   >> 297         return 0;
 74 }                                                 298 }
 75                                                   299 
 76 int __init register_persistent_clock(clock_acc !! 300 EXPORT_SYMBOL(do_settimeofday);
                                                   >> 301 
                                                   >> 302 /* This function is only called on the boot processor */
                                                   >> 303 void __init time_init(void)
 77 {                                                 304 {
 78         /* Only allow the clockaccess function !! 305         time_t sec, old_sec;
 79         if (__read_persistent_clock == dummy_c !! 306         unsigned old_stamp, stamp, elapsed;
 80                 if (read_persistent)           !! 307 
 81                         __read_persistent_cloc !! 308         if (ppc_md.time_init != NULL)
 82                 return 0;                      !! 309                 time_offset = ppc_md.time_init();
                                                   >> 310 
                                                   >> 311         if (__USE_RTC()) {
                                                   >> 312                 /* 601 processor: dec counts down by 128 every 128ns */
                                                   >> 313                 tb_ticks_per_jiffy = DECREMENTER_COUNT_601;
                                                   >> 314                 /* mulhwu_scale_factor(1000000000, 1000000) is 0x418937 */
                                                   >> 315                 tb_to_us = 0x418937;
                                                   >> 316         } else {
                                                   >> 317                 ppc_md.calibrate_decr();
                                                   >> 318                 tb_to_ns_scale = mulhwu(tb_to_us, 1000 << 10);
                                                   >> 319         }
                                                   >> 320 
                                                   >> 321         /* Now that the decrementer is calibrated, it can be used in case the
                                                   >> 322          * clock is stuck, but the fact that we have to handle the 601
                                                   >> 323          * makes things more complex. Repeatedly read the RTC until the
                                                   >> 324          * next second boundary to try to achieve some precision.  If there
                                                   >> 325          * is no RTC, we still need to set tb_last_stamp and
                                                   >> 326          * last_jiffy_stamp(cpu 0) to the current stamp.
                                                   >> 327          */
                                                   >> 328         stamp = get_native_tbl();
                                                   >> 329         if (ppc_md.get_rtc_time) {
                                                   >> 330                 sec = ppc_md.get_rtc_time();
                                                   >> 331                 elapsed = 0;
                                                   >> 332                 do {
                                                   >> 333                         old_stamp = stamp;
                                                   >> 334                         old_sec = sec;
                                                   >> 335                         stamp = get_native_tbl();
                                                   >> 336                         if (__USE_RTC() && stamp < old_stamp)
                                                   >> 337                                 old_stamp -= 1000000000;
                                                   >> 338                         elapsed += stamp - old_stamp;
                                                   >> 339                         sec = ppc_md.get_rtc_time();
                                                   >> 340                 } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
                                                   >> 341                 if (sec==old_sec)
                                                   >> 342                         printk("Warning: real time clock seems stuck!\n");
                                                   >> 343                 xtime.tv_sec = sec;
                                                   >> 344                 xtime.tv_nsec = 0;
                                                   >> 345                 /* No update now, we just read the time from the RTC ! */
                                                   >> 346                 last_rtc_update = xtime.tv_sec;
 83         }                                         347         }
                                                   >> 348         last_jiffy_stamp(0) = tb_last_stamp = stamp;
 84                                                   349 
 85         return -EINVAL;                        !! 350         /* Not exact, but the timer interrupt takes care of this */
                                                   >> 351         set_dec(tb_ticks_per_jiffy);
                                                   >> 352 
                                                   >> 353         /* If platform provided a timezone (pmac), we correct the time */
                                                   >> 354         if (time_offset) {
                                                   >> 355                 sys_tz.tz_minuteswest = -time_offset / 60;
                                                   >> 356                 sys_tz.tz_dsttime = 0;
                                                   >> 357                 xtime.tv_sec -= time_offset;
                                                   >> 358         }
                                                   >> 359         set_normalized_timespec(&wall_to_monotonic,
                                                   >> 360                                 -xtime.tv_sec, -xtime.tv_nsec);
 86 }                                                 361 }
 87                                                   362 
 88 void __init time_init(void)                    !! 363 #define FEBRUARY                2
                                                   >> 364 #define STARTOFTIME             1970
                                                   >> 365 #define SECDAY                  86400L
                                                   >> 366 #define SECYR                   (SECDAY * 365)
                                                   >> 367 
                                                   >> 368 /*
                                                   >> 369  * Note: this is wrong for 2100, but our signed 32-bit time_t will
                                                   >> 370  * have overflowed long before that, so who cares.  -- paulus
                                                   >> 371  */
                                                   >> 372 #define leapyear(year)          ((year) % 4 == 0)
                                                   >> 373 #define days_in_year(a)         (leapyear(a) ? 366 : 365)
                                                   >> 374 #define days_in_month(a)        (month_days[(a) - 1])
                                                   >> 375 
                                                   >> 376 static int month_days[12] = {
                                                   >> 377         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
                                                   >> 378 };
                                                   >> 379 
                                                   >> 380 void to_tm(int tim, struct rtc_time * tm)
                                                   >> 381 {
                                                   >> 382         register int i;
                                                   >> 383         register long hms, day, gday;
                                                   >> 384 
                                                   >> 385         gday = day = tim / SECDAY;
                                                   >> 386         hms = tim % SECDAY;
                                                   >> 387 
                                                   >> 388         /* Hours, minutes, seconds are easy */
                                                   >> 389         tm->tm_hour = hms / 3600;
                                                   >> 390         tm->tm_min = (hms % 3600) / 60;
                                                   >> 391         tm->tm_sec = (hms % 3600) % 60;
                                                   >> 392 
                                                   >> 393         /* Number of years in days */
                                                   >> 394         for (i = STARTOFTIME; day >= days_in_year(i); i++)
                                                   >> 395                 day -= days_in_year(i);
                                                   >> 396         tm->tm_year = i;
                                                   >> 397 
                                                   >> 398         /* Number of months in days left */
                                                   >> 399         if (leapyear(tm->tm_year))
                                                   >> 400                 days_in_month(FEBRUARY) = 29;
                                                   >> 401         for (i = 1; day >= days_in_month(i); i++)
                                                   >> 402                 day -= days_in_month(i);
                                                   >> 403         days_in_month(FEBRUARY) = 28;
                                                   >> 404         tm->tm_mon = i;
                                                   >> 405 
                                                   >> 406         /* Days are what is left over (+1) from all that. */
                                                   >> 407         tm->tm_mday = day + 1;
                                                   >> 408 
                                                   >> 409         /*
                                                   >> 410          * Determine the day of week. Jan. 1, 1970 was a Thursday.
                                                   >> 411          */
                                                   >> 412         tm->tm_wday = (gday + 4) % 7;
                                                   >> 413 }
                                                   >> 414 
                                                   >> 415 /* Auxiliary function to compute scaling factors */
                                                   >> 416 /* Actually the choice of a timebase running at 1/4 the of the bus
                                                   >> 417  * frequency giving resolution of a few tens of nanoseconds is quite nice.
                                                   >> 418  * It makes this computation very precise (27-28 bits typically) which
                                                   >> 419  * is optimistic considering the stability of most processor clock
                                                   >> 420  * oscillators and the precision with which the timebase frequency
                                                   >> 421  * is measured but does not harm.
                                                   >> 422  */
                                                   >> 423 unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
                                                   >> 424         unsigned mlt=0, tmp, err;
                                                   >> 425         /* No concern for performance, it's done once: use a stupid
                                                   >> 426          * but safe and compact method to find the multiplier.
                                                   >> 427          */
                                                   >> 428         for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
                                                   >> 429                 if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp;
                                                   >> 430         }
                                                   >> 431         /* We might still be off by 1 for the best approximation.
                                                   >> 432          * A side effect of this is that if outscale is too large
                                                   >> 433          * the returned value will be zero.
                                                   >> 434          * Many corner cases have been checked and seem to work,
                                                   >> 435          * some might have been forgotten in the test however.
                                                   >> 436          */
                                                   >> 437         err = inscale*(mlt+1);
                                                   >> 438         if (err <= inscale/2) mlt++;
                                                   >> 439         return mlt;
                                                   >> 440 }
                                                   >> 441 
                                                   >> 442 unsigned long long sched_clock(void)
 89 {                                                 443 {
 90         if (machine_desc->init_time) {         !! 444         unsigned long lo, hi, hi2;
 91                 machine_desc->init_time();     !! 445         unsigned long long tb;
                                                   >> 446 
                                                   >> 447         if (!__USE_RTC()) {
                                                   >> 448                 do {
                                                   >> 449                         hi = get_tbu();
                                                   >> 450                         lo = get_tbl();
                                                   >> 451                         hi2 = get_tbu();
                                                   >> 452                 } while (hi2 != hi);
                                                   >> 453                 tb = ((unsigned long long) hi << 32) | lo;
                                                   >> 454                 tb = (tb * tb_to_ns_scale) >> 10;
 92         } else {                                  455         } else {
 93 #ifdef CONFIG_COMMON_CLK                       !! 456                 do {
 94                 of_clk_init(NULL);             !! 457                         hi = get_rtcu();
 95 #endif                                         !! 458                         lo = get_rtcl();
 96                 timer_probe();                 !! 459                         hi2 = get_rtcu();
 97                 tick_setup_hrtimer_broadcast() !! 460                 } while (hi2 != hi);
                                                   >> 461                 tb = ((unsigned long long) hi) * 1000000000 + lo;
 98         }                                         462         }
                                                   >> 463         return tb;
 99 }                                                 464 }
100                                                   465 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php