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

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

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/sh/kernel/time.c (Version linux-6.12-rc7) and /arch/i386/kernel/time.c (Version linux-2.6.0)


  1 // SPDX-License-Identifier: GPL-2.0            << 
  2 /*                                                  1 /*
  3  *  arch/sh/kernel/time.c                      !!   2  *  linux/arch/i386/kernel/time.c
  4  *                                                  3  *
  5  *  Copyright (C) 1999  Tetsuya Okada & Niibe  !!   4  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
  6  *  Copyright (C) 2000  Philipp Rumpf <prumpf@ !!   5  *
  7  *  Copyright (C) 2002 - 2009  Paul Mundt      !!   6  * This file contains the PC-specific time handling details:
  8  *  Copyright (C) 2002  M. R. Brown  <mrbrown@ !!   7  * reading the RTC at bootup, etc..
                                                   >>   8  * 1994-07-02    Alan Modra
                                                   >>   9  *      fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
                                                   >>  10  * 1995-03-26    Markus Kuhn
                                                   >>  11  *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
                                                   >>  12  *      precision CMOS clock update
                                                   >>  13  * 1996-05-03    Ingo Molnar
                                                   >>  14  *      fixed time warps in do_[slow|fast]_gettimeoffset()
                                                   >>  15  * 1997-09-10   Updated NTP code according to technical memorandum Jan '96
                                                   >>  16  *              "A Kernel Model for Precision Timekeeping" by Dave Mills
                                                   >>  17  * 1998-09-05    (Various)
                                                   >>  18  *      More robust do_fast_gettimeoffset() algorithm implemented
                                                   >>  19  *      (works with APM, Cyrix 6x86MX and Centaur C6),
                                                   >>  20  *      monotonic gettimeofday() with fast_get_timeoffset(),
                                                   >>  21  *      drift-proof precision TSC calibration on boot
                                                   >>  22  *      (C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
                                                   >>  23  *      Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
                                                   >>  24  *      ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
                                                   >>  25  * 1998-12-16    Andrea Arcangeli
                                                   >>  26  *      Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
                                                   >>  27  *      because was not accounting lost_ticks.
                                                   >>  28  * 1998-12-24 Copyright (C) 1998  Andrea Arcangeli
                                                   >>  29  *      Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
                                                   >>  30  *      serialize accesses to xtime/lost_ticks).
  9  */                                                31  */
                                                   >>  32 
                                                   >>  33 #include <linux/errno.h>
                                                   >>  34 #include <linux/sched.h>
 10 #include <linux/kernel.h>                          35 #include <linux/kernel.h>
                                                   >>  36 #include <linux/param.h>
                                                   >>  37 #include <linux/string.h>
                                                   >>  38 #include <linux/mm.h>
                                                   >>  39 #include <linux/interrupt.h>
                                                   >>  40 #include <linux/time.h>
                                                   >>  41 #include <linux/delay.h>
 11 #include <linux/init.h>                            42 #include <linux/init.h>
 12 #include <linux/profile.h>                     << 
 13 #include <linux/timex.h>                       << 
 14 #include <linux/sched.h>                       << 
 15 #include <linux/clockchips.h>                  << 
 16 #include <linux/platform_device.h>             << 
 17 #include <linux/smp.h>                             43 #include <linux/smp.h>
 18 #include <linux/rtc.h>                         !!  44 #include <linux/module.h>
 19 #include <asm/clock.h>                         !!  45 #include <linux/sysdev.h>
 20 #include <asm/rtc.h>                           !!  46 #include <linux/bcd.h>
 21 #include <asm/platform_early.h>                !!  47 
                                                   >>  48 #include <asm/io.h>
                                                   >>  49 #include <asm/smp.h>
                                                   >>  50 #include <asm/irq.h>
                                                   >>  51 #include <asm/msr.h>
                                                   >>  52 #include <asm/delay.h>
                                                   >>  53 #include <asm/mpspec.h>
                                                   >>  54 #include <asm/uaccess.h>
                                                   >>  55 #include <asm/processor.h>
                                                   >>  56 #include <asm/timer.h>
                                                   >>  57 
                                                   >>  58 #include "mach_time.h"
                                                   >>  59 
                                                   >>  60 #include <linux/timex.h>
                                                   >>  61 #include <linux/config.h>
                                                   >>  62 
                                                   >>  63 #include <asm/hpet.h>
                                                   >>  64 
                                                   >>  65 #include <asm/arch_hooks.h>
                                                   >>  66 
                                                   >>  67 #include "io_ports.h"
                                                   >>  68 
                                                   >>  69 extern spinlock_t i8259A_lock;
                                                   >>  70 int pit_latch_buggy;              /* extern */
                                                   >>  71 
                                                   >>  72 #include "do_timer.h"
                                                   >>  73 
                                                   >>  74 u64 jiffies_64 = INITIAL_JIFFIES;
                                                   >>  75 
                                                   >>  76 EXPORT_SYMBOL(jiffies_64);
                                                   >>  77 
                                                   >>  78 unsigned long cpu_khz;  /* Detected as we calibrate the TSC */
                                                   >>  79 
                                                   >>  80 extern unsigned long wall_jiffies;
                                                   >>  81 
                                                   >>  82 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
                                                   >>  83 
                                                   >>  84 spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
                                                   >>  85 EXPORT_SYMBOL(i8253_lock);
                                                   >>  86 
                                                   >>  87 struct timer_opts *cur_timer = &timer_none;
                                                   >>  88 
                                                   >>  89 /*
                                                   >>  90  * This version of gettimeofday has microsecond resolution
                                                   >>  91  * and better than microsecond precision on fast x86 machines with TSC.
                                                   >>  92  */
                                                   >>  93 void do_gettimeofday(struct timeval *tv)
                                                   >>  94 {
                                                   >>  95         unsigned long seq;
                                                   >>  96         unsigned long usec, sec;
                                                   >>  97         unsigned long max_ntp_tick = tick_usec - tickadj;
                                                   >>  98 
                                                   >>  99         do {
                                                   >> 100                 unsigned long lost;
                                                   >> 101 
                                                   >> 102                 seq = read_seqbegin(&xtime_lock);
                                                   >> 103 
                                                   >> 104                 usec = cur_timer->get_offset();
                                                   >> 105                 lost = jiffies - wall_jiffies;
                                                   >> 106 
                                                   >> 107                 /*
                                                   >> 108                  * If time_adjust is negative then NTP is slowing the clock
                                                   >> 109                  * so make sure not to go into next possible interval.
                                                   >> 110                  * Better to lose some accuracy than have time go backwards..
                                                   >> 111                  */
                                                   >> 112                 if (unlikely(time_adjust < 0)) {
                                                   >> 113                         usec = min(usec, max_ntp_tick);
                                                   >> 114 
                                                   >> 115                         if (lost)
                                                   >> 116                                 usec += lost * max_ntp_tick;
                                                   >> 117                 }
                                                   >> 118                 else if (unlikely(lost))
                                                   >> 119                         usec += lost * tick_usec;
                                                   >> 120 
                                                   >> 121                 sec = xtime.tv_sec;
                                                   >> 122                 usec += (xtime.tv_nsec / 1000);
                                                   >> 123         } while (read_seqretry(&xtime_lock, seq));
                                                   >> 124 
                                                   >> 125         while (usec >= 1000000) {
                                                   >> 126                 usec -= 1000000;
                                                   >> 127                 sec++;
                                                   >> 128         }
                                                   >> 129 
                                                   >> 130         tv->tv_sec = sec;
                                                   >> 131         tv->tv_usec = usec;
                                                   >> 132 }
                                                   >> 133 
                                                   >> 134 EXPORT_SYMBOL(do_gettimeofday);
 22                                                   135 
 23 static void __init sh_late_time_init(void)     !! 136 int do_settimeofday(struct timespec *tv)
 24 {                                                 137 {
                                                   >> 138         time_t wtm_sec, sec = tv->tv_sec;
                                                   >> 139         long wtm_nsec, nsec = tv->tv_nsec;
                                                   >> 140 
                                                   >> 141         if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
                                                   >> 142                 return -EINVAL;
                                                   >> 143 
                                                   >> 144         write_seqlock_irq(&xtime_lock);
 25         /*                                        145         /*
 26          * Make sure all compiled-in early tim !! 146          * This is revolting. We need to set "xtime" correctly. However, the
 27          *                                     !! 147          * value in this location is the value at the most recent update of
 28          * Run probe() for two "earlytimer" de !! 148          * wall time.  Discover what correction gettimeofday() would have
 29          * clockevents and clocksource devices !! 149          * made, and then undo it!
 30          * that only a clockevents device is a << 
 31          * clocksource and the jiffies clockso << 
 32          * instead. No error handling is neces << 
 33          */                                       150          */
 34         sh_early_platform_driver_register_all( !! 151         nsec -= cur_timer->get_offset() * NSEC_PER_USEC;
 35         sh_early_platform_driver_probe("earlyt !! 152         nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
                                                   >> 153 
                                                   >> 154         wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
                                                   >> 155         wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
                                                   >> 156 
                                                   >> 157         set_normalized_timespec(&xtime, sec, nsec);
                                                   >> 158         set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
                                                   >> 159 
                                                   >> 160         time_adjust = 0;                /* stop active adjtime() */
                                                   >> 161         time_status |= STA_UNSYNC;
                                                   >> 162         time_maxerror = NTP_PHASE_LIMIT;
                                                   >> 163         time_esterror = NTP_PHASE_LIMIT;
                                                   >> 164         write_sequnlock_irq(&xtime_lock);
                                                   >> 165         clock_was_set();
                                                   >> 166         return 0;
                                                   >> 167 }
                                                   >> 168 
                                                   >> 169 EXPORT_SYMBOL(do_settimeofday);
                                                   >> 170 
                                                   >> 171 static int set_rtc_mmss(unsigned long nowtime)
                                                   >> 172 {
                                                   >> 173         int retval;
                                                   >> 174 
                                                   >> 175         /* gets recalled with irq locally disabled */
                                                   >> 176         spin_lock(&rtc_lock);
                                                   >> 177         retval = mach_set_rtc_mmss(nowtime);
                                                   >> 178         spin_unlock(&rtc_lock);
                                                   >> 179 
                                                   >> 180         return retval;
                                                   >> 181 }
                                                   >> 182 
                                                   >> 183 /* last time the cmos clock got updated */
                                                   >> 184 static long last_rtc_update;
                                                   >> 185 
                                                   >> 186 int timer_ack;
                                                   >> 187 
                                                   >> 188 /* monotonic_clock(): returns # of nanoseconds passed since time_init()
                                                   >> 189  *              Note: This function is required to return accurate
                                                   >> 190  *              time even in the absence of multiple timer ticks.
                                                   >> 191  */
                                                   >> 192 unsigned long long monotonic_clock(void)
                                                   >> 193 {
                                                   >> 194         return cur_timer->monotonic_clock();
                                                   >> 195 }
                                                   >> 196 EXPORT_SYMBOL(monotonic_clock);
                                                   >> 197 
                                                   >> 198 
                                                   >> 199 /*
                                                   >> 200  * timer_interrupt() needs to keep up the real-time clock,
                                                   >> 201  * as well as call the "do_timer()" routine every clocktick
                                                   >> 202  */
                                                   >> 203 static inline void do_timer_interrupt(int irq, void *dev_id,
                                                   >> 204                                         struct pt_regs *regs)
                                                   >> 205 {
                                                   >> 206 #ifdef CONFIG_X86_IO_APIC
                                                   >> 207         if (timer_ack) {
                                                   >> 208                 /*
                                                   >> 209                  * Subtle, when I/O APICs are used we have to ack timer IRQ
                                                   >> 210                  * manually to reset the IRR bit for do_slow_gettimeoffset().
                                                   >> 211                  * This will also deassert NMI lines for the watchdog if run
                                                   >> 212                  * on an 82489DX-based system.
                                                   >> 213                  */
                                                   >> 214                 spin_lock(&i8259A_lock);
                                                   >> 215                 outb(0x0c, PIC_MASTER_OCW3);
                                                   >> 216                 /* Ack the IRQ; AEOI will end it automatically. */
                                                   >> 217                 inb(PIC_MASTER_POLL);
                                                   >> 218                 spin_unlock(&i8259A_lock);
                                                   >> 219         }
                                                   >> 220 #endif
                                                   >> 221 
                                                   >> 222         do_timer_interrupt_hook(regs);
                                                   >> 223 
                                                   >> 224         /*
                                                   >> 225          * If we have an externally synchronized Linux clock, then update
                                                   >> 226          * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
                                                   >> 227          * called as close as possible to 500 ms before the new second starts.
                                                   >> 228          */
                                                   >> 229         if ((time_status & STA_UNSYNC) == 0 &&
                                                   >> 230             xtime.tv_sec > last_rtc_update + 660 &&
                                                   >> 231             (xtime.tv_nsec / 1000)
                                                   >> 232                         >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
                                                   >> 233             (xtime.tv_nsec / 1000)
                                                   >> 234                         <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) {
                                                   >> 235                 if (set_rtc_mmss(xtime.tv_sec) == 0)
                                                   >> 236                         last_rtc_update = xtime.tv_sec;
                                                   >> 237                 else
                                                   >> 238                         last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
                                                   >> 239         }
                                                   >> 240 
                                                   >> 241 #ifdef CONFIG_MCA
                                                   >> 242         if( MCA_bus ) {
                                                   >> 243                 /* The PS/2 uses level-triggered interrupts.  You can't
                                                   >> 244                 turn them off, nor would you want to (any attempt to
                                                   >> 245                 enable edge-triggered interrupts usually gets intercepted by a
                                                   >> 246                 special hardware circuit).  Hence we have to acknowledge
                                                   >> 247                 the timer interrupt.  Through some incredibly stupid
                                                   >> 248                 design idea, the reset for IRQ 0 is done by setting the
                                                   >> 249                 high bit of the PPI port B (0x61).  Note that some PS/2s,
                                                   >> 250                 notably the 55SX, work fine if this is removed.  */
                                                   >> 251 
                                                   >> 252                 irq = inb_p( 0x61 );    /* read the current state */
                                                   >> 253                 outb_p( irq|0x80, 0x61 );       /* reset the IRQ */
                                                   >> 254         }
                                                   >> 255 #endif
                                                   >> 256 }
                                                   >> 257 
                                                   >> 258 /*
                                                   >> 259  * This is the same as the above, except we _also_ save the current
                                                   >> 260  * Time Stamp Counter value at the time of the timer interrupt, so that
                                                   >> 261  * we later on can estimate the time of day more exactly.
                                                   >> 262  */
                                                   >> 263 irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                                   >> 264 {
                                                   >> 265         /*
                                                   >> 266          * Here we are in the timer irq handler. We just have irqs locally
                                                   >> 267          * disabled but we don't know if the timer_bh is running on the other
                                                   >> 268          * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
                                                   >> 269          * the irq version of write_lock because as just said we have irq
                                                   >> 270          * locally disabled. -arca
                                                   >> 271          */
                                                   >> 272         write_seqlock(&xtime_lock);
                                                   >> 273 
                                                   >> 274         cur_timer->mark_offset();
                                                   >> 275  
                                                   >> 276         do_timer_interrupt(irq, NULL, regs);
                                                   >> 277 
                                                   >> 278         write_sequnlock(&xtime_lock);
                                                   >> 279         return IRQ_HANDLED;
                                                   >> 280 }
                                                   >> 281 
                                                   >> 282 /* not static: needed by APM */
                                                   >> 283 unsigned long get_cmos_time(void)
                                                   >> 284 {
                                                   >> 285         unsigned long retval;
                                                   >> 286 
                                                   >> 287         spin_lock(&rtc_lock);
                                                   >> 288 
                                                   >> 289         retval = mach_get_cmos_time();
                                                   >> 290 
                                                   >> 291         spin_unlock(&rtc_lock);
                                                   >> 292 
                                                   >> 293         return retval;
                                                   >> 294 }
                                                   >> 295 
                                                   >> 296 static struct sysdev_class pit_sysclass = {
                                                   >> 297         set_kset_name("pit"),
                                                   >> 298 };
                                                   >> 299 
                                                   >> 300 /* XXX this driverfs stuff should probably go elsewhere later -john */
                                                   >> 301 static struct sys_device device_i8253 = {
                                                   >> 302         .id     = 0,
                                                   >> 303         .cls    = &pit_sysclass,
                                                   >> 304 };
                                                   >> 305 
                                                   >> 306 static int time_init_device(void)
                                                   >> 307 {
                                                   >> 308         int error = sysdev_class_register(&pit_sysclass);
                                                   >> 309         if (!error)
                                                   >> 310                 error = sys_device_register(&device_i8253);
                                                   >> 311         return error;
                                                   >> 312 }
                                                   >> 313 
                                                   >> 314 device_initcall(time_init_device);
                                                   >> 315 
                                                   >> 316 #ifdef CONFIG_HPET_TIMER
                                                   >> 317 extern void (*late_time_init)(void);
                                                   >> 318 /* Duplicate of time_init() below, with hpet_enable part added */
                                                   >> 319 void __init hpet_time_init(void)
                                                   >> 320 {
                                                   >> 321         xtime.tv_sec = get_cmos_time();
                                                   >> 322         wall_to_monotonic.tv_sec = -xtime.tv_sec;
                                                   >> 323         xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
                                                   >> 324         wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
                                                   >> 325 
                                                   >> 326         if (hpet_enable() >= 0) {
                                                   >> 327                 printk("Using HPET for base-timer\n");
                                                   >> 328         }
                                                   >> 329 
                                                   >> 330         cur_timer = select_timer();
                                                   >> 331         time_init_hook();
 36 }                                                 332 }
                                                   >> 333 #endif
 37                                                   334 
 38 void __init time_init(void)                       335 void __init time_init(void)
 39 {                                                 336 {
 40         timer_probe();                         !! 337 #ifdef CONFIG_HPET_TIMER
                                                   >> 338         if (is_hpet_capable()) {
                                                   >> 339                 /*
                                                   >> 340                  * HPET initialization needs to do memory-mapped io. So, let
                                                   >> 341                  * us do a late initialization after mem_init().
                                                   >> 342                  */
                                                   >> 343                 late_time_init = hpet_time_init;
                                                   >> 344                 return;
                                                   >> 345         }
                                                   >> 346 #endif
 41                                                   347 
 42         clk_init();                            !! 348         xtime.tv_sec = get_cmos_time();
                                                   >> 349         wall_to_monotonic.tv_sec = -xtime.tv_sec;
                                                   >> 350         xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
                                                   >> 351         wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 43                                                   352 
 44         late_time_init = sh_late_time_init;    !! 353         cur_timer = select_timer();
                                                   >> 354         time_init_hook();
 45 }                                                 355 }
 46                                                   356 

~ [ 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