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

TOMOYO Linux Cross Reference
Linux/arch/mips/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/mips/kernel/time.c (Version linux-6.12-rc7) and /arch/m68k/kernel/time.c (Version linux-2.4.37.11)


  1 // SPDX-License-Identifier: GPL-2.0-or-later   << 
  2 /*                                                  1 /*
  3  * Copyright 2001 MontaVista Software Inc.     !!   2  *  linux/arch/m68k/kernel/time.c
  4  * Author: Jun Sun, jsun@mvista.com or jsun@ju << 
  5  * Copyright (c) 2003, 2004  Maciej W. Rozycki << 
  6  *                                                  3  *
  7  * Common time service routines for MIPS machi !!   4  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
                                                   >>   5  *
                                                   >>   6  * This file contains the m68k-specific time handling details.
                                                   >>   7  * Most of the stuff is located in the machine specific files.
                                                   >>   8  *
                                                   >>   9  * 1997-09-10   Updated NTP code according to technical memorandum Jan '96
                                                   >>  10  *              "A Kernel Model for Precision Timekeeping" by Dave Mills
  8  */                                                11  */
  9 #include <linux/bug.h>                         !!  12 
 10 #include <linux/clockchips.h>                  !!  13 #include <linux/config.h> /* CONFIG_HEARTBEAT */
 11 #include <linux/types.h>                       !!  14 #include <linux/errno.h>
 12 #include <linux/kernel.h>                      << 
 13 #include <linux/init.h>                        << 
 14 #include <linux/sched.h>                           15 #include <linux/sched.h>
                                                   >>  16 #include <linux/kernel.h>
 15 #include <linux/param.h>                           17 #include <linux/param.h>
 16 #include <linux/time.h>                        !!  18 #include <linux/string.h>
 17 #include <linux/timex.h>                       !!  19 #include <linux/mm.h>
 18 #include <linux/smp.h>                         << 
 19 #include <linux/spinlock.h>                    << 
 20 #include <linux/export.h>                      << 
 21 #include <linux/cpufreq.h>                     << 
 22 #include <linux/delay.h>                       << 
 23                                                << 
 24 #include <asm/cpu-features.h>                  << 
 25 #include <asm/cpu-type.h>                      << 
 26 #include <asm/div64.h>                         << 
 27 #include <asm/time.h>                          << 
 28                                                << 
 29 #ifdef CONFIG_CPU_FREQ                         << 
 30                                                << 
 31 static DEFINE_PER_CPU(unsigned long, pcp_lpj_r << 
 32 static DEFINE_PER_CPU(unsigned long, pcp_lpj_r << 
 33 static unsigned long glb_lpj_ref;              << 
 34 static unsigned long glb_lpj_ref_freq;         << 
 35                                                << 
 36 static int cpufreq_callback(struct notifier_bl << 
 37                             unsigned long val, << 
 38 {                                              << 
 39         struct cpufreq_freqs *freq = data;     << 
 40         struct cpumask *cpus = freq->policy->c << 
 41         unsigned long lpj;                     << 
 42         int cpu;                               << 
 43                                                << 
 44         /*                                     << 
 45          * Skip lpj numbers adjustment if the  << 
 46          * the loops delay. (Is this possible? << 
 47          */                                    << 
 48         if (freq->flags & CPUFREQ_CONST_LOOPS) << 
 49                 return NOTIFY_OK;              << 
 50                                                    20 
 51         /* Save the initial values of the lpje !!  21 #include <asm/machdep.h>
 52         if (!glb_lpj_ref) {                    !!  22 #include <asm/io.h>
 53                 glb_lpj_ref = boot_cpu_data.ud << 
 54                 glb_lpj_ref_freq = freq->old;  << 
 55                                                << 
 56                 for_each_online_cpu(cpu) {     << 
 57                         per_cpu(pcp_lpj_ref, c << 
 58                                 cpu_data[cpu]. << 
 59                         per_cpu(pcp_lpj_ref_fr << 
 60                 }                              << 
 61         }                                      << 
 62                                                << 
 63         /*                                     << 
 64          * Adjust global lpj variable and per- << 
 65          * accordance with the new CPU frequen << 
 66          */                                    << 
 67         if ((val == CPUFREQ_PRECHANGE  && freq << 
 68             (val == CPUFREQ_POSTCHANGE && freq << 
 69                 loops_per_jiffy = cpufreq_scal << 
 70                                                << 
 71                                                << 
 72                                                << 
 73                 for_each_cpu(cpu, cpus) {      << 
 74                         lpj = cpufreq_scale(pe << 
 75                                             pe << 
 76                                             fr << 
 77                         cpu_data[cpu].udelay_v << 
 78                 }                              << 
 79         }                                      << 
 80                                                    23 
 81         return NOTIFY_OK;                      !!  24 #include <linux/timex.h>
 82 }                                              << 
 83                                                    25 
 84 static struct notifier_block cpufreq_notifier  << 
 85         .notifier_call  = cpufreq_callback,    << 
 86 };                                             << 
 87                                                    26 
 88 static int __init register_cpufreq_notifier(vo !!  27 static inline int set_rtc_mmss(unsigned long nowtime)
 89 {                                                  28 {
 90         return cpufreq_register_notifier(&cpuf !!  29   if (mach_set_clock_mmss)
 91                                          CPUFR !!  30     return mach_set_clock_mmss (nowtime);
                                                   >>  31   return -1;
 92 }                                                  32 }
 93 core_initcall(register_cpufreq_notifier);      << 
 94                                                    33 
 95 #endif /* CONFIG_CPU_FREQ */                   !!  34 static inline void do_profile (unsigned long pc)
                                                   >>  35 {
                                                   >>  36         if (prof_buffer && current->pid) {
                                                   >>  37                 extern int _stext;
                                                   >>  38                 pc -= (unsigned long) &_stext;
                                                   >>  39                 pc >>= prof_shift;
                                                   >>  40                 if (pc < prof_len)
                                                   >>  41                         ++prof_buffer[pc];
                                                   >>  42                 else
                                                   >>  43                 /*
                                                   >>  44                  * Don't ignore out-of-bounds PC values silently,
                                                   >>  45                  * put them into the last histogram slot, so if
                                                   >>  46                  * present, they will show up as a sharp peak.
                                                   >>  47                  */
                                                   >>  48                         ++prof_buffer[prof_len-1];
                                                   >>  49         }
                                                   >>  50 }
 96                                                    51 
 97 /*                                                 52 /*
 98  * forward reference                           !!  53  * timer_interrupt() needs to keep up the real-time clock,
                                                   >>  54  * as well as call the "do_timer()" routine every clocktick
 99  */                                                55  */
100 DEFINE_SPINLOCK(rtc_lock);                     !!  56 static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
101 EXPORT_SYMBOL(rtc_lock);                       << 
102                                                << 
103 static int null_perf_irq(void)                 << 
104 {                                                  57 {
105         return 0;                              !!  58         do_timer(regs);
                                                   >>  59 
                                                   >>  60         if (!user_mode(regs))
                                                   >>  61                 do_profile(regs->pc);
                                                   >>  62 
                                                   >>  63 #ifdef CONFIG_HEARTBEAT
                                                   >>  64         /* use power LED as a heartbeat instead -- much more useful
                                                   >>  65            for debugging -- based on the version for PReP by Cort */
                                                   >>  66         /* acts like an actual heart beat -- ie thump-thump-pause... */
                                                   >>  67         if (mach_heartbeat) {
                                                   >>  68             static unsigned cnt = 0, period = 0, dist = 0;
                                                   >>  69 
                                                   >>  70             if (cnt == 0 || cnt == dist)
                                                   >>  71                 mach_heartbeat( 1 );
                                                   >>  72             else if (cnt == 7 || cnt == dist+7)
                                                   >>  73                 mach_heartbeat( 0 );
                                                   >>  74 
                                                   >>  75             if (++cnt > period) {
                                                   >>  76                 cnt = 0;
                                                   >>  77                 /* The hyperbolic function below modifies the heartbeat period
                                                   >>  78                  * length in dependency of the current (5min) load. It goes
                                                   >>  79                  * through the points f(0)=126, f(1)=86, f(5)=51,
                                                   >>  80                  * f(inf)->30. */
                                                   >>  81                 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
                                                   >>  82                 dist = period / 4;
                                                   >>  83             }
                                                   >>  84         }
                                                   >>  85 #endif /* CONFIG_HEARTBEAT */
106 }                                                  86 }
107                                                    87 
108 int (*perf_irq)(void) = null_perf_irq;         !!  88 void time_init(void)
                                                   >>  89 {
                                                   >>  90         unsigned int year, mon, day, hour, min, sec;
109                                                    91 
110 EXPORT_SYMBOL(perf_irq);                       !!  92         extern void arch_gettod(int *year, int *mon, int *day, int *hour,
                                                   >>  93                                 int *min, int *sec);
111                                                    94 
112 /*                                             !!  95         arch_gettod (&year, &mon, &day, &hour, &min, &sec);
113  * time_init() - it does the following things. << 
114  *                                             << 
115  * 1) plat_time_init() -                       << 
116  *      a) (optional) set up RTC routines,     << 
117  *      b) (optional) calibrate and set the mi << 
118  *          (only needed if you intended to us << 
119  *           source)                           << 
120  * 2) calculate a couple of cached variables f << 
121  */                                            << 
122                                                    96 
123 unsigned int mips_hpt_frequency;               !!  97         if ((year += 1900) < 1970)
124 EXPORT_SYMBOL_GPL(mips_hpt_frequency);         !!  98                 year += 100;
                                                   >>  99         xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
                                                   >> 100         xtime.tv_usec = 0;
125                                                   101 
126 static __init int cpu_has_mfc0_count_bug(void) !! 102         mach_sched_init(timer_interrupt);
127 {                                              !! 103 }
128         switch (current_cpu_type()) {          << 
129         case CPU_R4000PC:                      << 
130         case CPU_R4000SC:                      << 
131         case CPU_R4000MC:                      << 
132                 /*                             << 
133                  * V3.0 is documented as suffe << 
134                  * Afaik this is the last vers << 
135                  * were marketed as R4400.     << 
136                  */                            << 
137                 return 1;                      << 
138                                                   104 
139         case CPU_R4400PC:                      !! 105 extern rwlock_t xtime_lock;
140         case CPU_R4400SC:                      !! 106 
141         case CPU_R4400MC:                      !! 107 /*
142                 /*                             !! 108  * This version of gettimeofday has near microsecond resolution.
143                  * The published errata for th !! 109  */
144                  * has the mfc0 from count bug !! 110 void do_gettimeofday(struct timeval *tv)
145                  * produced.                   !! 111 {
146                  */                            !! 112         extern unsigned long wall_jiffies;
147                 return 1;                      !! 113         unsigned long flags;
                                                   >> 114         unsigned long usec, sec, lost;
                                                   >> 115 
                                                   >> 116         read_lock_irqsave(&xtime_lock, flags);
                                                   >> 117         usec = mach_gettimeoffset();
                                                   >> 118         lost = jiffies - wall_jiffies;
                                                   >> 119         if (lost)
                                                   >> 120                 usec += lost * (1000000/HZ);
                                                   >> 121         sec = xtime.tv_sec;
                                                   >> 122         usec += xtime.tv_usec;
                                                   >> 123         read_unlock_irqrestore(&xtime_lock, flags);
                                                   >> 124 
                                                   >> 125         while (usec >= 1000000) {
                                                   >> 126                 usec -= 1000000;
                                                   >> 127                 sec++;
148         }                                         128         }
149                                                   129 
150         return 0;                              !! 130         tv->tv_sec = sec;
                                                   >> 131         tv->tv_usec = usec;
151 }                                                 132 }
152                                                   133 
153 void __init time_init(void)                    !! 134 void do_settimeofday(struct timeval *tv)
154 {                                                 135 {
155         plat_time_init();                      !! 136         write_lock_irq(&xtime_lock);
156                                                !! 137         /* This is revolting. We need to set the xtime.tv_usec
157         /*                                     !! 138          * correctly. However, the value in this location is
158          * The use of the R4k timer as a clock !! 139          * is value at the last tick.
159          * if reading the Count register might !! 140          * Discover what correction gettimeofday
160          * interrupt, then we don't use the ti !! 141          * would have done, and then undo it!
161          * We may still use the timer as a clo << 
162          * timer interrupt isn't reliable; the << 
163          * matter then, because we don't use t << 
164          */                                       142          */
165         if (mips_clockevent_init() != 0 || !cp !! 143         tv->tv_usec -= mach_gettimeoffset();
166                 init_mips_clocksource();       !! 144 
                                                   >> 145         while (tv->tv_usec < 0) {
                                                   >> 146                 tv->tv_usec += 1000000;
                                                   >> 147                 tv->tv_sec--;
                                                   >> 148         }
                                                   >> 149 
                                                   >> 150         xtime = *tv;
                                                   >> 151         time_adjust = 0;                /* stop active adjtime() */
                                                   >> 152         time_status |= STA_UNSYNC;
                                                   >> 153         time_maxerror = NTP_PHASE_LIMIT;
                                                   >> 154         time_esterror = NTP_PHASE_LIMIT;
                                                   >> 155         write_unlock_irq(&xtime_lock);
167 }                                                 156 }
168                                                   157 

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