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

TOMOYO Linux Cross Reference
Linux/arch/arm/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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arm/kernel/time.c (Architecture ppc) and /arch/alpha/kernel/time.c (Architecture alpha)


  1 // SPDX-License-Identifier: GPL-2.0-only       !!   1 // SPDX-License-Identifier: GPL-2.0
  2 /*                                                  2 /*
  3  *  linux/arch/arm/kernel/time.c               !!   3  *  linux/arch/alpha/kernel/time.c
  4  *                                                  4  *
  5  *  Copyright (C) 1991, 1992, 1995  Linus Torv !!   5  *  Copyright (C) 1991, 1992, 1995, 1999, 2000  Linus Torvalds
  6  *  Modifications for ARM (C) 1994-2001 Russel << 
  7  *                                                  6  *
  8  *  This file contains the ARM-specific time h !!   7  * This file contains the clocksource time handling.
  9  *  reading the RTC at bootup, etc...          !!   8  * 1997-09-10   Updated NTP code according to technical memorandum Jan '96
                                                   >>   9  *              "A Kernel Model for Precision Timekeeping" by Dave Mills
                                                   >>  10  * 1997-01-09    Adrian Sun
                                                   >>  11  *      use interval timer if CONFIG_RTC=y
                                                   >>  12  * 1997-10-29    John Bowman (bowman@math.ualberta.ca)
                                                   >>  13  *      fixed tick loss calculation in timer_interrupt
                                                   >>  14  *      (round system clock to nearest tick instead of truncating)
                                                   >>  15  *      fixed algorithm in time_init for getting time from CMOS clock
                                                   >>  16  * 1999-04-16   Thorsten Kranzkowski (dl8bcu@gmx.net)
                                                   >>  17  *      fixed algorithm in do_gettimeofday() for calculating the precise time
                                                   >>  18  *      from processor cycle counter (now taking lost_ticks into account)
                                                   >>  19  * 2003-06-03   R. Scott Bailey <scott.bailey@eds.com>
                                                   >>  20  *      Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM
 10  */                                                21  */
 11 #include <linux/clockchips.h>                  << 
 12 #include <linux/clocksource.h>                 << 
 13 #include <linux/errno.h>                           22 #include <linux/errno.h>
 14 #include <linux/export.h>                      !!  23 #include <linux/module.h>
 15 #include <linux/init.h>                        !!  24 #include <linux/sched.h>
 16 #include <linux/interrupt.h>                   << 
 17 #include <linux/irq.h>                         << 
 18 #include <linux/kernel.h>                          25 #include <linux/kernel.h>
 19 #include <linux/of_clk.h>                      !!  26 #include <linux/param.h>
                                                   >>  27 #include <linux/string.h>
                                                   >>  28 #include <linux/mm.h>
                                                   >>  29 #include <linux/delay.h>
                                                   >>  30 #include <linux/ioport.h>
                                                   >>  31 #include <linux/irq.h>
                                                   >>  32 #include <linux/interrupt.h>
                                                   >>  33 #include <linux/init.h>
                                                   >>  34 #include <linux/bcd.h>
 20 #include <linux/profile.h>                         35 #include <linux/profile.h>
 21 #include <linux/sched.h>                       !!  36 #include <linux/irq_work.h>
 22 #include <linux/sched_clock.h>                 !!  37 
 23 #include <linux/smp.h>                         !!  38 #include <linux/uaccess.h>
                                                   >>  39 #include <asm/io.h>
                                                   >>  40 #include <asm/hwrpb.h>
                                                   >>  41 
                                                   >>  42 #include <linux/mc146818rtc.h>
 24 #include <linux/time.h>                            43 #include <linux/time.h>
 25 #include <linux/timex.h>                           44 #include <linux/timex.h>
 26 #include <linux/timer.h>                       !!  45 #include <linux/clocksource.h>
                                                   >>  46 #include <linux/clockchips.h>
                                                   >>  47 
                                                   >>  48 #include "proto.h"
                                                   >>  49 #include "irq_impl.h"
 27                                                    50 
 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);                         51 DEFINE_SPINLOCK(rtc_lock);
 37 EXPORT_SYMBOL(rtc_lock);                           52 EXPORT_SYMBOL(rtc_lock);
 38 #endif  /* pc-style 'CMOS' RTC support */      << 
 39                                                    53 
 40 /* change this if you have some constant time  !!  54 unsigned long est_cycle_freq;
 41 #define USECS_PER_JIFFY (1000000/HZ)           << 
 42                                                    55 
 43 #ifdef CONFIG_SMP                              !!  56 #ifdef CONFIG_IRQ_WORK
 44 unsigned long profile_pc(struct pt_regs *regs) !!  57 
                                                   >>  58 DEFINE_PER_CPU(u8, irq_work_pending);
                                                   >>  59 
                                                   >>  60 #define set_irq_work_pending_flag()  __this_cpu_write(irq_work_pending, 1)
                                                   >>  61 #define test_irq_work_pending()      __this_cpu_read(irq_work_pending)
                                                   >>  62 #define clear_irq_work_pending()     __this_cpu_write(irq_work_pending, 0)
                                                   >>  63 
                                                   >>  64 void arch_irq_work_raise(void)
 45 {                                                  65 {
 46         struct stackframe frame;               !!  66         set_irq_work_pending_flag();
                                                   >>  67 }
 47                                                    68 
 48         if (!in_lock_functions(regs->ARM_pc))  !!  69 #else  /* CONFIG_IRQ_WORK */
 49                 return regs->ARM_pc;           << 
 50                                                    70 
 51         arm_get_current_stackframe(regs, &fram !!  71 #define test_irq_work_pending()      0
 52         do {                                   !!  72 #define clear_irq_work_pending()
 53                 int ret = unwind_frame(&frame) !!  73 
 54                 if (ret < 0)                   !!  74 #endif /* CONFIG_IRQ_WORK */
 55                         return 0;              !!  75 
 56         } while (in_lock_functions(frame.pc)); !!  76 
                                                   >>  77 static inline __u32 rpcc(void)
                                                   >>  78 {
                                                   >>  79         return __builtin_alpha_rpcc();
                                                   >>  80 }
                                                   >>  81 
                                                   >>  82 
                                                   >>  83 
                                                   >>  84 /*
                                                   >>  85  * The RTC as a clock_event_device primitive.
                                                   >>  86  */
                                                   >>  87 
                                                   >>  88 static DEFINE_PER_CPU(struct clock_event_device, cpu_ce);
                                                   >>  89 
                                                   >>  90 irqreturn_t
                                                   >>  91 rtc_timer_interrupt(int irq, void *dev)
                                                   >>  92 {
                                                   >>  93         int cpu = smp_processor_id();
                                                   >>  94         struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
                                                   >>  95 
                                                   >>  96         /* Don't run the hook for UNUSED or SHUTDOWN.  */
                                                   >>  97         if (likely(clockevent_state_periodic(ce)))
                                                   >>  98                 ce->event_handler(ce);
                                                   >>  99 
                                                   >> 100         if (test_irq_work_pending()) {
                                                   >> 101                 clear_irq_work_pending();
                                                   >> 102                 irq_work_run();
                                                   >> 103         }
                                                   >> 104 
                                                   >> 105         return IRQ_HANDLED;
                                                   >> 106 }
                                                   >> 107 
                                                   >> 108 static int
                                                   >> 109 rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
                                                   >> 110 {
                                                   >> 111         /* This hook is for oneshot mode, which we don't support.  */
                                                   >> 112         return -EINVAL;
                                                   >> 113 }
                                                   >> 114 
                                                   >> 115 static void __init
                                                   >> 116 init_rtc_clockevent(void)
                                                   >> 117 {
                                                   >> 118         int cpu = smp_processor_id();
                                                   >> 119         struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
                                                   >> 120 
                                                   >> 121         *ce = (struct clock_event_device){
                                                   >> 122                 .name = "rtc",
                                                   >> 123                 .features = CLOCK_EVT_FEAT_PERIODIC,
                                                   >> 124                 .rating = 100,
                                                   >> 125                 .cpumask = cpumask_of(cpu),
                                                   >> 126                 .set_next_event = rtc_ce_set_next_event,
                                                   >> 127         };
                                                   >> 128 
                                                   >> 129         clockevents_config_and_register(ce, CONFIG_HZ, 0, 0);
                                                   >> 130 }
                                                   >> 131 
                                                   >> 132 
                                                   >> 133 /*
                                                   >> 134  * The QEMU clock as a clocksource primitive.
                                                   >> 135  */
                                                   >> 136 
                                                   >> 137 static u64
                                                   >> 138 qemu_cs_read(struct clocksource *cs)
                                                   >> 139 {
                                                   >> 140         return qemu_get_vmtime();
                                                   >> 141 }
                                                   >> 142 
                                                   >> 143 static struct clocksource qemu_cs = {
                                                   >> 144         .name                   = "qemu",
                                                   >> 145         .rating                 = 400,
                                                   >> 146         .read                   = qemu_cs_read,
                                                   >> 147         .mask                   = CLOCKSOURCE_MASK(64),
                                                   >> 148         .flags                  = CLOCK_SOURCE_IS_CONTINUOUS,
                                                   >> 149         .max_idle_ns            = LONG_MAX
                                                   >> 150 };
                                                   >> 151 
                                                   >> 152 
                                                   >> 153 /*
                                                   >> 154  * The QEMU alarm as a clock_event_device primitive.
                                                   >> 155  */
                                                   >> 156 
                                                   >> 157 static int qemu_ce_shutdown(struct clock_event_device *ce)
                                                   >> 158 {
                                                   >> 159         /* The mode member of CE is updated for us in generic code.
                                                   >> 160            Just make sure that the event is disabled.  */
                                                   >> 161         qemu_set_alarm_abs(0);
                                                   >> 162         return 0;
                                                   >> 163 }
                                                   >> 164 
                                                   >> 165 static int
                                                   >> 166 qemu_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
                                                   >> 167 {
                                                   >> 168         qemu_set_alarm_rel(evt);
                                                   >> 169         return 0;
                                                   >> 170 }
 57                                                   171 
 58         return frame.pc;                       !! 172 static irqreturn_t
                                                   >> 173 qemu_timer_interrupt(int irq, void *dev)
                                                   >> 174 {
                                                   >> 175         int cpu = smp_processor_id();
                                                   >> 176         struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
                                                   >> 177 
                                                   >> 178         ce->event_handler(ce);
                                                   >> 179         return IRQ_HANDLED;
 59 }                                                 180 }
 60 EXPORT_SYMBOL(profile_pc);                     !! 181 
                                                   >> 182 static void __init
                                                   >> 183 init_qemu_clockevent(void)
                                                   >> 184 {
                                                   >> 185         int cpu = smp_processor_id();
                                                   >> 186         struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
                                                   >> 187 
                                                   >> 188         *ce = (struct clock_event_device){
                                                   >> 189                 .name = "qemu",
                                                   >> 190                 .features = CLOCK_EVT_FEAT_ONESHOT,
                                                   >> 191                 .rating = 400,
                                                   >> 192                 .cpumask = cpumask_of(cpu),
                                                   >> 193                 .set_state_shutdown = qemu_ce_shutdown,
                                                   >> 194                 .set_state_oneshot = qemu_ce_shutdown,
                                                   >> 195                 .tick_resume = qemu_ce_shutdown,
                                                   >> 196                 .set_next_event = qemu_ce_set_next_event,
                                                   >> 197         };
                                                   >> 198 
                                                   >> 199         clockevents_config_and_register(ce, NSEC_PER_SEC, 1000, LONG_MAX);
                                                   >> 200 }
                                                   >> 201 
                                                   >> 202 
                                                   >> 203 void __init
                                                   >> 204 common_init_rtc(void)
                                                   >> 205 {
                                                   >> 206         unsigned char x, sel = 0;
                                                   >> 207 
                                                   >> 208         /* Reset periodic interrupt frequency.  */
                                                   >> 209 #if CONFIG_HZ == 1024 || CONFIG_HZ == 1200
                                                   >> 210         x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f;
                                                   >> 211         /* Test includes known working values on various platforms
                                                   >> 212            where 0x26 is wrong; we refuse to change those. */
                                                   >> 213         if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) {
                                                   >> 214                 sel = RTC_REF_CLCK_32KHZ + 6;
                                                   >> 215         }
                                                   >> 216 #elif CONFIG_HZ == 256 || CONFIG_HZ == 128 || CONFIG_HZ == 64 || CONFIG_HZ == 32
                                                   >> 217         sel = RTC_REF_CLCK_32KHZ + __builtin_ffs(32768 / CONFIG_HZ);
                                                   >> 218 #else
                                                   >> 219 # error "Unknown HZ from arch/alpha/Kconfig"
 61 #endif                                            220 #endif
                                                   >> 221         if (sel) {
                                                   >> 222                 printk(KERN_INFO "Setting RTC_FREQ to %d Hz (%x)\n",
                                                   >> 223                        CONFIG_HZ, sel);
                                                   >> 224                 CMOS_WRITE(sel, RTC_FREQ_SELECT);
                                                   >> 225         }
                                                   >> 226 
                                                   >> 227         /* Turn on periodic interrupts.  */
                                                   >> 228         x = CMOS_READ(RTC_CONTROL);
                                                   >> 229         if (!(x & RTC_PIE)) {
                                                   >> 230                 printk("Turning on RTC interrupts.\n");
                                                   >> 231                 x |= RTC_PIE;
                                                   >> 232                 x &= ~(RTC_AIE | RTC_UIE);
                                                   >> 233                 CMOS_WRITE(x, RTC_CONTROL);
                                                   >> 234         }
                                                   >> 235         (void) CMOS_READ(RTC_INTR_FLAGS);
                                                   >> 236 
                                                   >> 237         outb(0x36, 0x43);       /* pit counter 0: system timer */
                                                   >> 238         outb(0x00, 0x40);
                                                   >> 239         outb(0x00, 0x40);
                                                   >> 240 
                                                   >> 241         outb(0xb6, 0x43);       /* pit counter 2: speaker */
                                                   >> 242         outb(0x31, 0x42);
                                                   >> 243         outb(0x13, 0x42);
                                                   >> 244 
                                                   >> 245         init_rtc_irq(NULL);
                                                   >> 246 }
 62                                                   247 
 63 static void dummy_clock_access(struct timespec !! 248 
                                                   >> 249 #ifndef CONFIG_ALPHA_WTINT
                                                   >> 250 /*
                                                   >> 251  * The RPCC as a clocksource primitive.
                                                   >> 252  *
                                                   >> 253  * While we have free-running timecounters running on all CPUs, and we make
                                                   >> 254  * a half-hearted attempt in init_rtc_rpcc_info to sync the timecounter
                                                   >> 255  * with the wall clock, that initialization isn't kept up-to-date across
                                                   >> 256  * different time counters in SMP mode.  Therefore we can only use this
                                                   >> 257  * method when there's only one CPU enabled.
                                                   >> 258  *
                                                   >> 259  * When using the WTINT PALcall, the RPCC may shift to a lower frequency,
                                                   >> 260  * or stop altogether, while waiting for the interrupt.  Therefore we cannot
                                                   >> 261  * use this method when WTINT is in use.
                                                   >> 262  */
                                                   >> 263 
                                                   >> 264 static u64 read_rpcc(struct clocksource *cs)
 64 {                                                 265 {
 65         ts->tv_sec = 0;                        !! 266         return rpcc();
 66         ts->tv_nsec = 0;                       << 
 67 }                                                 267 }
 68                                                   268 
 69 static clock_access_fn __read_persistent_clock !! 269 static struct clocksource clocksource_rpcc = {
                                                   >> 270         .name                   = "rpcc",
                                                   >> 271         .rating                 = 300,
                                                   >> 272         .read                   = read_rpcc,
                                                   >> 273         .mask                   = CLOCKSOURCE_MASK(32),
                                                   >> 274         .flags                  = CLOCK_SOURCE_IS_CONTINUOUS
                                                   >> 275 };
                                                   >> 276 #endif /* ALPHA_WTINT */
                                                   >> 277 
                                                   >> 278 
                                                   >> 279 /* Validate a computed cycle counter result against the known bounds for
                                                   >> 280    the given processor core.  There's too much brokenness in the way of
                                                   >> 281    timing hardware for any one method to work everywhere.  :-(
 70                                                   282 
 71 void read_persistent_clock64(struct timespec64 !! 283    Return 0 if the result cannot be trusted, otherwise return the argument.  */
                                                   >> 284 
                                                   >> 285 static unsigned long __init
                                                   >> 286 validate_cc_value(unsigned long cc)
 72 {                                                 287 {
 73         __read_persistent_clock(ts);           !! 288         static struct bounds {
                                                   >> 289                 unsigned int min, max;
                                                   >> 290         } cpu_hz[] __initdata = {
                                                   >> 291                 [EV3_CPU]    = {   50000000,  200000000 },      /* guess */
                                                   >> 292                 [EV4_CPU]    = {  100000000,  300000000 },
                                                   >> 293                 [LCA4_CPU]   = {  100000000,  300000000 },      /* guess */
                                                   >> 294                 [EV45_CPU]   = {  200000000,  300000000 },
                                                   >> 295                 [EV5_CPU]    = {  250000000,  433000000 },
                                                   >> 296                 [EV56_CPU]   = {  333000000,  667000000 },
                                                   >> 297                 [PCA56_CPU]  = {  400000000,  600000000 },      /* guess */
                                                   >> 298                 [PCA57_CPU]  = {  500000000,  600000000 },      /* guess */
                                                   >> 299                 [EV6_CPU]    = {  466000000,  600000000 },
                                                   >> 300                 [EV67_CPU]   = {  600000000,  750000000 },
                                                   >> 301                 [EV68AL_CPU] = {  750000000,  940000000 },
                                                   >> 302                 [EV68CB_CPU] = { 1000000000, 1333333333 },
                                                   >> 303                 /* None of the following are shipping as of 2001-11-01.  */
                                                   >> 304                 [EV68CX_CPU] = { 1000000000, 1700000000 },      /* guess */
                                                   >> 305                 [EV69_CPU]   = { 1000000000, 1700000000 },      /* guess */
                                                   >> 306                 [EV7_CPU]    = {  800000000, 1400000000 },      /* guess */
                                                   >> 307                 [EV79_CPU]   = { 1000000000, 2000000000 },      /* guess */
                                                   >> 308         };
                                                   >> 309 
                                                   >> 310         /* Allow for some drift in the crystal.  10MHz is more than enough.  */
                                                   >> 311         const unsigned int deviation = 10000000;
                                                   >> 312 
                                                   >> 313         struct percpu_struct *cpu;
                                                   >> 314         unsigned int index;
                                                   >> 315 
                                                   >> 316         cpu = (struct percpu_struct *)((char*)hwrpb + hwrpb->processor_offset);
                                                   >> 317         index = cpu->type & 0xffffffff;
                                                   >> 318 
                                                   >> 319         /* If index out of bounds, no way to validate.  */
                                                   >> 320         if (index >= ARRAY_SIZE(cpu_hz))
                                                   >> 321                 return cc;
                                                   >> 322 
                                                   >> 323         /* If index contains no data, no way to validate.  */
                                                   >> 324         if (cpu_hz[index].max == 0)
                                                   >> 325                 return cc;
                                                   >> 326 
                                                   >> 327         if (cc < cpu_hz[index].min - deviation
                                                   >> 328             || cc > cpu_hz[index].max + deviation)
                                                   >> 329                 return 0;
                                                   >> 330 
                                                   >> 331         return cc;
 74 }                                                 332 }
 75                                                   333 
 76 int __init register_persistent_clock(clock_acc !! 334 
                                                   >> 335 /*
                                                   >> 336  * Calibrate CPU clock using legacy 8254 timer/counter. Stolen from
                                                   >> 337  * arch/i386/time.c.
                                                   >> 338  */
                                                   >> 339 
                                                   >> 340 #define CALIBRATE_LATCH 0xffff
                                                   >> 341 #define TIMEOUT_COUNT   0x100000
                                                   >> 342 
                                                   >> 343 static unsigned long __init
                                                   >> 344 calibrate_cc_with_pit(void)
 77 {                                                 345 {
 78         /* Only allow the clockaccess function !! 346         int cc, count = 0;
 79         if (__read_persistent_clock == dummy_c !! 347 
 80                 if (read_persistent)           !! 348         /* Set the Gate high, disable speaker */
 81                         __read_persistent_cloc !! 349         outb((inb(0x61) & ~0x02) | 0x01, 0x61);
                                                   >> 350 
                                                   >> 351         /*
                                                   >> 352          * Now let's take care of CTC channel 2
                                                   >> 353          *
                                                   >> 354          * Set the Gate high, program CTC channel 2 for mode 0,
                                                   >> 355          * (interrupt on terminal count mode), binary count,
                                                   >> 356          * load 5 * LATCH count, (LSB and MSB) to begin countdown.
                                                   >> 357          */
                                                   >> 358         outb(0xb0, 0x43);               /* binary, mode 0, LSB/MSB, Ch 2 */
                                                   >> 359         outb(CALIBRATE_LATCH & 0xff, 0x42);     /* LSB of count */
                                                   >> 360         outb(CALIBRATE_LATCH >> 8, 0x42);       /* MSB of count */
                                                   >> 361 
                                                   >> 362         cc = rpcc();
                                                   >> 363         do {
                                                   >> 364                 count++;
                                                   >> 365         } while ((inb(0x61) & 0x20) == 0 && count < TIMEOUT_COUNT);
                                                   >> 366         cc = rpcc() - cc;
                                                   >> 367 
                                                   >> 368         /* Error: ECTCNEVERSET or ECPUTOOFAST.  */
                                                   >> 369         if (count <= 1 || count == TIMEOUT_COUNT)
 82                 return 0;                         370                 return 0;
 83         }                                      << 
 84                                                   371 
 85         return -EINVAL;                        !! 372         return ((long)cc * PIT_TICK_RATE) / (CALIBRATE_LATCH + 1);
 86 }                                                 373 }
 87                                                   374 
 88 void __init time_init(void)                    !! 375 /* The Linux interpretation of the CMOS clock register contents:
                                                   >> 376    When the Update-In-Progress (UIP) flag goes from 1 to 0, the
                                                   >> 377    RTC registers show the second which has precisely just started.
                                                   >> 378    Let's hope other operating systems interpret the RTC the same way.  */
                                                   >> 379 
                                                   >> 380 static unsigned long __init
                                                   >> 381 rpcc_after_update_in_progress(void)
 89 {                                                 382 {
 90         if (machine_desc->init_time) {         !! 383         do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
 91                 machine_desc->init_time();     !! 384         do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
 92         } else {                               !! 385 
 93 #ifdef CONFIG_COMMON_CLK                       !! 386         return rpcc();
 94                 of_clk_init(NULL);             !! 387 }
 95 #endif                                         !! 388 
 96                 timer_probe();                 !! 389 void __init
 97                 tick_setup_hrtimer_broadcast() !! 390 time_init(void)
                                                   >> 391 {
                                                   >> 392         unsigned int cc1, cc2;
                                                   >> 393         unsigned long cycle_freq, tolerance;
                                                   >> 394         long diff;
                                                   >> 395 
                                                   >> 396         if (alpha_using_qemu) {
                                                   >> 397                 clocksource_register_hz(&qemu_cs, NSEC_PER_SEC);
                                                   >> 398                 init_qemu_clockevent();
                                                   >> 399                 init_rtc_irq(qemu_timer_interrupt);
                                                   >> 400                 return;
                                                   >> 401         }
                                                   >> 402 
                                                   >> 403         /* Calibrate CPU clock -- attempt #1.  */
                                                   >> 404         if (!est_cycle_freq)
                                                   >> 405                 est_cycle_freq = validate_cc_value(calibrate_cc_with_pit());
                                                   >> 406 
                                                   >> 407         cc1 = rpcc();
                                                   >> 408 
                                                   >> 409         /* Calibrate CPU clock -- attempt #2.  */
                                                   >> 410         if (!est_cycle_freq) {
                                                   >> 411                 cc1 = rpcc_after_update_in_progress();
                                                   >> 412                 cc2 = rpcc_after_update_in_progress();
                                                   >> 413                 est_cycle_freq = validate_cc_value(cc2 - cc1);
                                                   >> 414                 cc1 = cc2;
 98         }                                         415         }
                                                   >> 416 
                                                   >> 417         cycle_freq = hwrpb->cycle_freq;
                                                   >> 418         if (est_cycle_freq) {
                                                   >> 419                 /* If the given value is within 250 PPM of what we calculated,
                                                   >> 420                    accept it.  Otherwise, use what we found.  */
                                                   >> 421                 tolerance = cycle_freq / 4000;
                                                   >> 422                 diff = cycle_freq - est_cycle_freq;
                                                   >> 423                 if (diff < 0)
                                                   >> 424                         diff = -diff;
                                                   >> 425                 if ((unsigned long)diff > tolerance) {
                                                   >> 426                         cycle_freq = est_cycle_freq;
                                                   >> 427                         printk("HWRPB cycle frequency bogus.  "
                                                   >> 428                                "Estimated %lu Hz\n", cycle_freq);
                                                   >> 429                 } else {
                                                   >> 430                         est_cycle_freq = 0;
                                                   >> 431                 }
                                                   >> 432         } else if (! validate_cc_value (cycle_freq)) {
                                                   >> 433                 printk("HWRPB cycle frequency bogus, "
                                                   >> 434                        "and unable to estimate a proper value!\n");
                                                   >> 435         }
                                                   >> 436 
                                                   >> 437         /* See above for restrictions on using clocksource_rpcc.  */
                                                   >> 438 #ifndef CONFIG_ALPHA_WTINT
                                                   >> 439         if (hwrpb->nr_processors == 1)
                                                   >> 440                 clocksource_register_hz(&clocksource_rpcc, cycle_freq);
                                                   >> 441 #endif
                                                   >> 442 
                                                   >> 443         /* Startup the timer source. */
                                                   >> 444         alpha_mv.init_rtc();
                                                   >> 445         init_rtc_clockevent();
 99 }                                                 446 }
                                                   >> 447 
                                                   >> 448 /* Initialize the clock_event_device for secondary cpus.  */
                                                   >> 449 #ifdef CONFIG_SMP
                                                   >> 450 void __init
                                                   >> 451 init_clockevent(void)
                                                   >> 452 {
                                                   >> 453         if (alpha_using_qemu)
                                                   >> 454                 init_qemu_clockevent();
                                                   >> 455         else
                                                   >> 456                 init_rtc_clockevent();
                                                   >> 457 }
                                                   >> 458 #endif
100                                                   459 

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