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


  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/errno.h>
 11 #include <linux/types.h>                       !!  14 #include <linux/export.h>
 12 #include <linux/kernel.h>                      !!  15 #include <linux/module.h>
 13 #include <linux/init.h>                        << 
 14 #include <linux/sched.h>                           16 #include <linux/sched.h>
                                                   >>  17 #include <linux/kernel.h>
 15 #include <linux/param.h>                           18 #include <linux/param.h>
                                                   >>  19 #include <linux/string.h>
                                                   >>  20 #include <linux/mm.h>
                                                   >>  21 #include <linux/rtc.h>
                                                   >>  22 #include <linux/platform_device.h>
                                                   >>  23 
                                                   >>  24 #include <asm/machdep.h>
                                                   >>  25 #include <asm/io.h>
                                                   >>  26 #include <asm/irq_regs.h>
                                                   >>  27 
 16 #include <linux/time.h>                            28 #include <linux/time.h>
 17 #include <linux/timex.h>                           29 #include <linux/timex.h>
 18 #include <linux/smp.h>                         !!  30 #include <linux/profile.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                                                << 
 51         /* Save the initial values of the lpje << 
 52         if (!glb_lpj_ref) {                    << 
 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                                                    31 
 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                                                    32 
 81         return NOTIFY_OK;                      !!  33 unsigned long (*mach_random_get_entropy)(void);
 82 }                                              !!  34 EXPORT_SYMBOL_GPL(mach_random_get_entropy);
 83                                                    35 
 84 static struct notifier_block cpufreq_notifier  << 
 85         .notifier_call  = cpufreq_callback,    << 
 86 };                                             << 
 87                                                    36 
 88 static int __init register_cpufreq_notifier(vo !!  37 /*
                                                   >>  38  * timer_interrupt() needs to keep up the real-time clock,
                                                   >>  39  * as well as call the "xtime_update()" routine every clocktick
                                                   >>  40  */
                                                   >>  41 static irqreturn_t timer_interrupt(int irq, void *dummy)
 89 {                                                  42 {
 90         return cpufreq_register_notifier(&cpuf !!  43         xtime_update(1);
 91                                          CPUFR !!  44         update_process_times(user_mode(get_irq_regs()));
                                                   >>  45         profile_tick(CPU_PROFILING);
                                                   >>  46 
                                                   >>  47 #ifdef CONFIG_HEARTBEAT
                                                   >>  48         /* use power LED as a heartbeat instead -- much more useful
                                                   >>  49            for debugging -- based on the version for PReP by Cort */
                                                   >>  50         /* acts like an actual heart beat -- ie thump-thump-pause... */
                                                   >>  51         if (mach_heartbeat) {
                                                   >>  52             static unsigned cnt = 0, period = 0, dist = 0;
                                                   >>  53 
                                                   >>  54             if (cnt == 0 || cnt == dist)
                                                   >>  55                 mach_heartbeat( 1 );
                                                   >>  56             else if (cnt == 7 || cnt == dist+7)
                                                   >>  57                 mach_heartbeat( 0 );
                                                   >>  58 
                                                   >>  59             if (++cnt > period) {
                                                   >>  60                 cnt = 0;
                                                   >>  61                 /* The hyperbolic function below modifies the heartbeat period
                                                   >>  62                  * length in dependency of the current (5min) load. It goes
                                                   >>  63                  * through the points f(0)=126, f(1)=86, f(5)=51,
                                                   >>  64                  * f(inf)->30. */
                                                   >>  65                 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
                                                   >>  66                 dist = period / 4;
                                                   >>  67             }
                                                   >>  68         }
                                                   >>  69 #endif /* CONFIG_HEARTBEAT */
                                                   >>  70         return IRQ_HANDLED;
 92 }                                                  71 }
 93 core_initcall(register_cpufreq_notifier);      << 
 94                                                    72 
 95 #endif /* CONFIG_CPU_FREQ */                   !!  73 void read_persistent_clock(struct timespec *ts)
                                                   >>  74 {
                                                   >>  75         struct rtc_time time;
                                                   >>  76         ts->tv_sec = 0;
                                                   >>  77         ts->tv_nsec = 0;
                                                   >>  78 
                                                   >>  79         if (mach_hwclk) {
                                                   >>  80                 mach_hwclk(0, &time);
                                                   >>  81 
                                                   >>  82                 if ((time.tm_year += 1900) < 1970)
                                                   >>  83                         time.tm_year += 100;
                                                   >>  84                 ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
                                                   >>  85                                       time.tm_hour, time.tm_min, time.tm_sec);
                                                   >>  86         }
                                                   >>  87 }
 96                                                    88 
 97 /*                                             !!  89 #if defined(CONFIG_ARCH_USES_GETTIMEOFFSET) && IS_ENABLED(CONFIG_RTC_DRV_GENERIC)
 98  * forward reference                           !!  90 static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm)
 99  */                                            !!  91 {
100 DEFINE_SPINLOCK(rtc_lock);                     !!  92         mach_hwclk(0, tm);
101 EXPORT_SYMBOL(rtc_lock);                       !!  93         return rtc_valid_tm(tm);
                                                   >>  94 }
102                                                    95 
103 static int null_perf_irq(void)                 !!  96 static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm)
104 {                                                  97 {
                                                   >>  98         if (mach_hwclk(1, tm) < 0)
                                                   >>  99                 return -EOPNOTSUPP;
105         return 0;                                 100         return 0;
106 }                                                 101 }
107                                                   102 
108 int (*perf_irq)(void) = null_perf_irq;         !! 103 static int rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
                                                   >> 104 {
                                                   >> 105         struct rtc_pll_info pll;
                                                   >> 106         struct rtc_pll_info __user *argp = (void __user *)arg;
109                                                   107 
110 EXPORT_SYMBOL(perf_irq);                       !! 108         switch (cmd) {
                                                   >> 109         case RTC_PLL_GET:
                                                   >> 110                 if (!mach_get_rtc_pll || mach_get_rtc_pll(&pll))
                                                   >> 111                         return -EINVAL;
                                                   >> 112                 return copy_to_user(argp, &pll, sizeof pll) ? -EFAULT : 0;
                                                   >> 113 
                                                   >> 114         case RTC_PLL_SET:
                                                   >> 115                 if (!mach_set_rtc_pll)
                                                   >> 116                         return -EINVAL;
                                                   >> 117                 if (!capable(CAP_SYS_TIME))
                                                   >> 118                         return -EACCES;
                                                   >> 119                 if (copy_from_user(&pll, argp, sizeof(pll)))
                                                   >> 120                         return -EFAULT;
                                                   >> 121                 return mach_set_rtc_pll(&pll);
                                                   >> 122         }
111                                                   123 
112 /*                                             !! 124         return -ENOIOCTLCMD;
113  * time_init() - it does the following things. !! 125 }
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                                                   126 
123 unsigned int mips_hpt_frequency;               !! 127 static const struct rtc_class_ops generic_rtc_ops = {
124 EXPORT_SYMBOL_GPL(mips_hpt_frequency);         !! 128         .ioctl = rtc_ioctl,
                                                   >> 129         .read_time = rtc_generic_get_time,
                                                   >> 130         .set_time = rtc_generic_set_time,
                                                   >> 131 };
125                                                   132 
126 static __init int cpu_has_mfc0_count_bug(void) !! 133 static int __init rtc_init(void)
127 {                                                 134 {
128         switch (current_cpu_type()) {          !! 135         struct platform_device *pdev;
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                                                << 
139         case CPU_R4400PC:                      << 
140         case CPU_R4400SC:                      << 
141         case CPU_R4400MC:                      << 
142                 /*                             << 
143                  * The published errata for th << 
144                  * has the mfc0 from count bug << 
145                  * produced.                   << 
146                  */                            << 
147                 return 1;                      << 
148         }                                      << 
149                                                   136 
150         return 0;                              !! 137         if (!mach_hwclk)
                                                   >> 138                 return -ENODEV;
                                                   >> 139 
                                                   >> 140         pdev = platform_device_register_data(NULL, "rtc-generic", -1,
                                                   >> 141                                              &generic_rtc_ops,
                                                   >> 142                                              sizeof(generic_rtc_ops));
                                                   >> 143         return PTR_ERR_OR_ZERO(pdev);
151 }                                                 144 }
152                                                   145 
                                                   >> 146 module_init(rtc_init);
                                                   >> 147 
                                                   >> 148 #endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
                                                   >> 149 
153 void __init time_init(void)                       150 void __init time_init(void)
154 {                                                 151 {
155         plat_time_init();                      !! 152         mach_sched_init(timer_interrupt);
156                                                << 
157         /*                                     << 
158          * The use of the R4k timer as a clock << 
159          * if reading the Count register might << 
160          * interrupt, then we don't use the ti << 
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          */                                    << 
165         if (mips_clockevent_init() != 0 || !cp << 
166                 init_mips_clocksource();       << 
167 }                                                 153 }
168                                                   154 

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