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

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


  1 // SPDX-License-Identifier: GPL-2.0-only       !!   1 /* $Id: time.c,v 1.60 2002/01/23 14:33:55 davem Exp $
                                                   >>   2  * linux/arch/sparc/kernel/time.c
                                                   >>   3  *
                                                   >>   4  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
                                                   >>   5  * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
                                                   >>   6  *
                                                   >>   7  * Chris Davis (cdavis@cois.on.ca) 03/27/1998
                                                   >>   8  * Added support for the intersil on the sun4/4200
                                                   >>   9  *
                                                   >>  10  * Gleb Raiko (rajko@mech.math.msu.su) 08/18/1998
                                                   >>  11  * Support for MicroSPARC-IIep, PCI CPU.
                                                   >>  12  *
                                                   >>  13  * This file handles the Sparc specific time handling details.
                                                   >>  14  *
                                                   >>  15  * 1997-09-10   Updated NTP code according to technical memorandum Jan '96
                                                   >>  16  *              "A Kernel Model for Precision Timekeeping" by Dave Mills
                                                   >>  17  */
                                                   >>  18 #include <linux/config.h>
                                                   >>  19 #include <linux/errno.h>
                                                   >>  20 #include <linux/module.h>
                                                   >>  21 #include <linux/sched.h>
                                                   >>  22 #include <linux/kernel.h>
                                                   >>  23 #include <linux/param.h>
                                                   >>  24 #include <linux/string.h>
                                                   >>  25 #include <linux/mm.h>
                                                   >>  26 #include <linux/interrupt.h>
                                                   >>  27 #include <linux/time.h>
                                                   >>  28 #include <linux/timex.h>
                                                   >>  29 #include <linux/init.h>
                                                   >>  30 #include <linux/pci.h>
                                                   >>  31 #include <linux/ioport.h>
                                                   >>  32 #include <linux/profile.h>
                                                   >>  33 
                                                   >>  34 #include <asm/oplib.h>
                                                   >>  35 #include <asm/segment.h>
                                                   >>  36 #include <asm/timer.h>
                                                   >>  37 #include <asm/mostek.h>
                                                   >>  38 #include <asm/system.h>
                                                   >>  39 #include <asm/irq.h>
                                                   >>  40 #include <asm/io.h>
                                                   >>  41 #include <asm/idprom.h>
                                                   >>  42 #include <asm/machines.h>
                                                   >>  43 #include <asm/sun4paddr.h>
                                                   >>  44 #include <asm/page.h>
                                                   >>  45 #include <asm/pcic.h>
                                                   >>  46 
                                                   >>  47 extern unsigned long wall_jiffies;
                                                   >>  48 
                                                   >>  49 u64 jiffies_64 = INITIAL_JIFFIES;
                                                   >>  50 
                                                   >>  51 EXPORT_SYMBOL(jiffies_64);
                                                   >>  52 
                                                   >>  53 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
                                                   >>  54 enum sparc_clock_type sp_clock_typ;
                                                   >>  55 spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
                                                   >>  56 unsigned long mstk48t02_regs = 0UL;
                                                   >>  57 static struct mostek48t08 *mstk48t08_regs = 0;
                                                   >>  58 static int set_rtc_mmss(unsigned long);
                                                   >>  59 static int sbus_do_settimeofday(struct timespec *tv);
                                                   >>  60 
                                                   >>  61 #ifdef CONFIG_SUN4
                                                   >>  62 struct intersil *intersil_clock;
                                                   >>  63 #define intersil_cmd(intersil_reg, intsil_cmd) intersil_reg->int_cmd_reg = \
                                                   >>  64         (intsil_cmd)
                                                   >>  65 
                                                   >>  66 #define intersil_intr(intersil_reg, intsil_cmd) intersil_reg->int_intr_reg = \
                                                   >>  67         (intsil_cmd)
                                                   >>  68 
                                                   >>  69 #define intersil_start(intersil_reg) intersil_cmd(intersil_reg, \
                                                   >>  70         ( INTERSIL_START | INTERSIL_32K | INTERSIL_NORMAL | INTERSIL_24H |\
                                                   >>  71           INTERSIL_INTR_ENABLE))
                                                   >>  72 
                                                   >>  73 #define intersil_stop(intersil_reg) intersil_cmd(intersil_reg, \
                                                   >>  74         ( INTERSIL_STOP | INTERSIL_32K | INTERSIL_NORMAL | INTERSIL_24H |\
                                                   >>  75           INTERSIL_INTR_ENABLE))
                                                   >>  76 
                                                   >>  77 #define intersil_read_intr(intersil_reg, towhere) towhere = \
                                                   >>  78         intersil_reg->int_intr_reg
                                                   >>  79 
                                                   >>  80 #endif
                                                   >>  81 
                                                   >>  82 static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
                                                   >>  83 
                                                   >>  84 /* 32-bit Sparc specific profiling function. */
                                                   >>  85 void sparc_do_profile(unsigned long pc, unsigned long o7)
                                                   >>  86 {
                                                   >>  87         if(prof_buffer && current->pid) {
                                                   >>  88                 extern int _stext;
                                                   >>  89                 extern int __copy_user_begin, __copy_user_end;
                                                   >>  90                 extern int __atomic_begin, __atomic_end;
                                                   >>  91                 extern int __bzero_begin, __bzero_end;
                                                   >>  92                 extern int __bitops_begin, __bitops_end;
                                                   >>  93 
                                                   >>  94                 if ((pc >= (unsigned long) &__copy_user_begin &&
                                                   >>  95                      pc < (unsigned long) &__copy_user_end) ||
                                                   >>  96                     (pc >= (unsigned long) &__atomic_begin &&
                                                   >>  97                      pc < (unsigned long) &__atomic_end) ||
                                                   >>  98                     (pc >= (unsigned long) &__bzero_begin &&
                                                   >>  99                      pc < (unsigned long) &__bzero_end) ||
                                                   >> 100                     (pc >= (unsigned long) &__bitops_begin &&
                                                   >> 101                      pc < (unsigned long) &__bitops_end))
                                                   >> 102                         pc = o7;
                                                   >> 103 
                                                   >> 104                 pc -= (unsigned long) &_stext;
                                                   >> 105                 pc >>= prof_shift;
                                                   >> 106 
                                                   >> 107                 spin_lock(&ticker_lock);
                                                   >> 108                 if(pc < prof_len)
                                                   >> 109                         prof_buffer[pc]++;
                                                   >> 110                 else
                                                   >> 111                         prof_buffer[prof_len - 1]++;
                                                   >> 112                 spin_unlock(&ticker_lock);
                                                   >> 113         }
                                                   >> 114 }
                                                   >> 115 
                                                   >> 116 __volatile__ unsigned int *master_l10_counter;
                                                   >> 117 __volatile__ unsigned int *master_l10_limit;
                                                   >> 118 
  2 /*                                                119 /*
  3  * Copyright (C) 2012 Regents of the Universit !! 120  * timer_interrupt() needs to keep up the real-time clock,
  4  * Copyright (C) 2017 SiFive                   !! 121  * as well as call the "do_timer()" routine every clocktick
  5  */                                               122  */
  6                                                   123 
  7 #include <linux/acpi.h>                        !! 124 #define TICK_SIZE (tick_nsec / 1000)
  8 #include <linux/of_clk.h>                      !! 125 
  9 #include <linux/clockchips.h>                  !! 126 irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 10 #include <linux/clocksource.h>                 !! 127 {
 11 #include <linux/delay.h>                       !! 128         /* last time the cmos clock got updated */
 12 #include <asm/sbi.h>                           !! 129         static long last_rtc_update;
 13 #include <asm/processor.h>                     << 
 14 #include <asm/timex.h>                         << 
 15 #include <asm/paravirt.h>                      << 
 16                                                   130 
 17 unsigned long riscv_timebase __ro_after_init;  !! 131 #ifndef CONFIG_SMP
 18 EXPORT_SYMBOL_GPL(riscv_timebase);             !! 132         if(!user_mode(regs))
                                                   >> 133                 sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]);
                                                   >> 134 #endif
 19                                                   135 
 20 void __init time_init(void)                    !! 136         /* Protect counter clear so that do_gettimeoffset works */
                                                   >> 137         write_seqlock(&xtime_lock);
                                                   >> 138 #ifdef CONFIG_SUN4
                                                   >> 139         if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) ||
                                                   >> 140            (idprom->id_machtype == (SM_SUN4 | SM_4_110))) {
                                                   >> 141                 int temp;
                                                   >> 142                 intersil_read_intr(intersil_clock, temp);
                                                   >> 143                 /* re-enable the irq */
                                                   >> 144                 enable_pil_irq(10);
                                                   >> 145         }
                                                   >> 146 #endif
                                                   >> 147         clear_clock_irq();
                                                   >> 148 
                                                   >> 149         do_timer(regs);
                                                   >> 150 
                                                   >> 151         /* Determine when to update the Mostek clock. */
                                                   >> 152         if ((time_status & STA_UNSYNC) == 0 &&
                                                   >> 153             xtime.tv_sec > last_rtc_update + 660 &&
                                                   >> 154             (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
                                                   >> 155             (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
                                                   >> 156           if (set_rtc_mmss(xtime.tv_sec) == 0)
                                                   >> 157             last_rtc_update = xtime.tv_sec;
                                                   >> 158           else
                                                   >> 159             last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
                                                   >> 160         }
                                                   >> 161         write_sequnlock(&xtime_lock);
                                                   >> 162 
                                                   >> 163         return IRQ_HANDLED;
                                                   >> 164 }
                                                   >> 165 
                                                   >> 166 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
                                                   >> 167 static void __init kick_start_clock(void)
 21 {                                                 168 {
 22         struct device_node *cpu;               !! 169         struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
 23         struct acpi_table_rhct *rhct;          !! 170         unsigned char sec;
 24         acpi_status status;                    !! 171         int i, count;
 25         u32 prop;                              !! 172 
 26                                                !! 173         prom_printf("CLOCK: Clock was stopped. Kick start ");
 27         if (acpi_disabled) {                   !! 174 
 28                 cpu = of_find_node_by_path("/c !! 175         spin_lock_irq(&mostek_lock);
 29                 if (!cpu || of_property_read_u !! 176 
 30                         panic("RISC-V system w !! 177         /* Turn on the kick start bit to start the oscillator. */
 31                                                !! 178         regs->creg |= MSTK_CREG_WRITE;
 32                 of_node_put(cpu);              !! 179         regs->sec &= ~MSTK_STOP;
 33                 riscv_timebase = prop;         !! 180         regs->hour |= MSTK_KICK_START;
 34                 of_clk_init(NULL);             !! 181         regs->creg &= ~MSTK_CREG_WRITE;
                                                   >> 182 
                                                   >> 183         spin_unlock_irq(&mostek_lock);
                                                   >> 184 
                                                   >> 185         /* Delay to allow the clock oscillator to start. */
                                                   >> 186         sec = MSTK_REG_SEC(regs);
                                                   >> 187         for (i = 0; i < 3; i++) {
                                                   >> 188                 while (sec == MSTK_REG_SEC(regs))
                                                   >> 189                         for (count = 0; count < 100000; count++)
                                                   >> 190                                 /* nothing */ ;
                                                   >> 191                 prom_printf(".");
                                                   >> 192                 sec = regs->sec;
                                                   >> 193         }
                                                   >> 194         prom_printf("\n");
                                                   >> 195 
                                                   >> 196         spin_lock_irq(&mostek_lock);
                                                   >> 197 
                                                   >> 198         /* Turn off kick start and set a "valid" time and date. */
                                                   >> 199         regs->creg |= MSTK_CREG_WRITE;
                                                   >> 200         regs->hour &= ~MSTK_KICK_START;
                                                   >> 201         MSTK_SET_REG_SEC(regs,0);
                                                   >> 202         MSTK_SET_REG_MIN(regs,0);
                                                   >> 203         MSTK_SET_REG_HOUR(regs,0);
                                                   >> 204         MSTK_SET_REG_DOW(regs,5);
                                                   >> 205         MSTK_SET_REG_DOM(regs,1);
                                                   >> 206         MSTK_SET_REG_MONTH(regs,8);
                                                   >> 207         MSTK_SET_REG_YEAR(regs,1996 - MSTK_YEAR_ZERO);
                                                   >> 208         regs->creg &= ~MSTK_CREG_WRITE;
                                                   >> 209 
                                                   >> 210         spin_unlock_irq(&mostek_lock);
                                                   >> 211 
                                                   >> 212         /* Ensure the kick start bit is off. If it isn't, turn it off. */
                                                   >> 213         while (regs->hour & MSTK_KICK_START) {
                                                   >> 214                 prom_printf("CLOCK: Kick start still on!\n");
                                                   >> 215 
                                                   >> 216                 spin_lock_irq(&mostek_lock);
                                                   >> 217                 regs->creg |= MSTK_CREG_WRITE;
                                                   >> 218                 regs->hour &= ~MSTK_KICK_START;
                                                   >> 219                 regs->creg &= ~MSTK_CREG_WRITE;
                                                   >> 220                 spin_unlock_irq(&mostek_lock);
                                                   >> 221         }
                                                   >> 222 
                                                   >> 223         prom_printf("CLOCK: Kick start procedure successful.\n");
                                                   >> 224 }
                                                   >> 225 
                                                   >> 226 /* Return nonzero if the clock chip battery is low. */
                                                   >> 227 static __inline__ int has_low_battery(void)
                                                   >> 228 {
                                                   >> 229         struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
                                                   >> 230         unsigned char data1, data2;
                                                   >> 231 
                                                   >> 232         spin_lock_irq(&mostek_lock);
                                                   >> 233         data1 = regs->eeprom[0];        /* Read some data. */
                                                   >> 234         regs->eeprom[0] = ~data1;       /* Write back the complement. */
                                                   >> 235         data2 = regs->eeprom[0];        /* Read back the complement. */
                                                   >> 236         regs->eeprom[0] = data1;        /* Restore the original value. */
                                                   >> 237         spin_unlock_irq(&mostek_lock);
                                                   >> 238 
                                                   >> 239         return (data1 == data2);        /* Was the write blocked? */
                                                   >> 240 }
                                                   >> 241 
                                                   >> 242 /* Probe for the real time clock chip on Sun4 */
                                                   >> 243 static __inline__ void sun4_clock_probe(void)
                                                   >> 244 {
                                                   >> 245 #ifdef CONFIG_SUN4
                                                   >> 246         int temp;
                                                   >> 247         struct resource r;
                                                   >> 248 
                                                   >> 249         memset(&r, 0, sizeof(r));
                                                   >> 250         if( idprom->id_machtype == (SM_SUN4 | SM_4_330) ) {
                                                   >> 251                 sp_clock_typ = MSTK48T02;
                                                   >> 252                 r.start = sun4_clock_physaddr;
                                                   >> 253                 mstk48t02_regs = sbus_ioremap(&r, 0,
                                                   >> 254                                        sizeof(struct mostek48t02), 0);
                                                   >> 255                 mstk48t08_regs = 0;  /* To catch weirdness */
                                                   >> 256                 intersil_clock = 0;  /* just in case */
                                                   >> 257 
                                                   >> 258                 /* Kick start the clock if it is completely stopped. */
                                                   >> 259                 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
                                                   >> 260                         kick_start_clock();
                                                   >> 261         } else if( idprom->id_machtype == (SM_SUN4 | SM_4_260)) {
                                                   >> 262                 /* intersil setup code */
                                                   >> 263                 printk("Clock: INTERSIL at %8x ",sun4_clock_physaddr);
                                                   >> 264                 sp_clock_typ = INTERSIL;
                                                   >> 265                 r.start = sun4_clock_physaddr;
                                                   >> 266                 intersil_clock = (struct intersil *) 
                                                   >> 267                     sbus_ioremap(&r, 0, sizeof(*intersil_clock), "intersil");
                                                   >> 268                 mstk48t02_regs = 0;  /* just be sure */
                                                   >> 269                 mstk48t08_regs = 0;  /* ditto */
                                                   >> 270                 /* initialise the clock */
                                                   >> 271 
                                                   >> 272                 intersil_intr(intersil_clock,INTERSIL_INT_100HZ);
                                                   >> 273 
                                                   >> 274                 intersil_start(intersil_clock);
                                                   >> 275 
                                                   >> 276                 intersil_read_intr(intersil_clock, temp);
                                                   >> 277                 while (!(temp & 0x80))
                                                   >> 278                         intersil_read_intr(intersil_clock, temp);
                                                   >> 279 
                                                   >> 280                 intersil_read_intr(intersil_clock, temp);
                                                   >> 281                 while (!(temp & 0x80))
                                                   >> 282                         intersil_read_intr(intersil_clock, temp);
                                                   >> 283 
                                                   >> 284                 intersil_stop(intersil_clock);
                                                   >> 285 
                                                   >> 286         }
                                                   >> 287 #endif
                                                   >> 288 }
                                                   >> 289 
                                                   >> 290 /* Probe for the mostek real time clock chip. */
                                                   >> 291 static __inline__ void clock_probe(void)
                                                   >> 292 {
                                                   >> 293         struct linux_prom_registers clk_reg[2];
                                                   >> 294         char model[128];
                                                   >> 295         register int node, cpuunit, bootbus;
                                                   >> 296         struct resource r;
                                                   >> 297 
                                                   >> 298         cpuunit = bootbus = 0;
                                                   >> 299         memset(&r, 0, sizeof(r));
                                                   >> 300 
                                                   >> 301         /* Determine the correct starting PROM node for the probe. */
                                                   >> 302         node = prom_getchild(prom_root_node);
                                                   >> 303         switch (sparc_cpu_model) {
                                                   >> 304         case sun4c:
                                                   >> 305                 break;
                                                   >> 306         case sun4m:
                                                   >> 307                 node = prom_getchild(prom_searchsiblings(node, "obio"));
                                                   >> 308                 break;
                                                   >> 309         case sun4d:
                                                   >> 310                 node = prom_getchild(bootbus = prom_searchsiblings(prom_getchild(cpuunit = prom_searchsiblings(node, "cpu-unit")), "bootbus"));
                                                   >> 311                 break;
                                                   >> 312         default:
                                                   >> 313                 prom_printf("CLOCK: Unsupported architecture!\n");
                                                   >> 314                 prom_halt();
                                                   >> 315         }
                                                   >> 316 
                                                   >> 317         /* Find the PROM node describing the real time clock. */
                                                   >> 318         sp_clock_typ = MSTK_INVALID;
                                                   >> 319         node = prom_searchsiblings(node,"eeprom");
                                                   >> 320         if (!node) {
                                                   >> 321                 prom_printf("CLOCK: No clock found!\n");
                                                   >> 322                 prom_halt();
                                                   >> 323         }
                                                   >> 324 
                                                   >> 325         /* Get the model name and setup everything up. */
                                                   >> 326         model[0] = '\0';
                                                   >> 327         prom_getstring(node, "model", model, sizeof(model));
                                                   >> 328         if (strcmp(model, "mk48t02") == 0) {
                                                   >> 329                 sp_clock_typ = MSTK48T02;
                                                   >> 330                 if (prom_getproperty(node, "reg", (char *) clk_reg, sizeof(clk_reg)) == -1) {
                                                   >> 331                         prom_printf("clock_probe: FAILED!\n");
                                                   >> 332                         prom_halt();
                                                   >> 333                 }
                                                   >> 334                 if (sparc_cpu_model == sun4d)
                                                   >> 335                         prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
                                                   >> 336                 else
                                                   >> 337                         prom_apply_obio_ranges(clk_reg, 1);
                                                   >> 338                 /* Map the clock register io area read-only */
                                                   >> 339                 r.flags = clk_reg[0].which_io;
                                                   >> 340                 r.start = clk_reg[0].phys_addr;
                                                   >> 341                 mstk48t02_regs = sbus_ioremap(&r, 0,
                                                   >> 342                     sizeof(struct mostek48t02), "mk48t02");
                                                   >> 343                 mstk48t08_regs = 0;  /* To catch weirdness */
                                                   >> 344         } else if (strcmp(model, "mk48t08") == 0) {
                                                   >> 345                 sp_clock_typ = MSTK48T08;
                                                   >> 346                 if(prom_getproperty(node, "reg", (char *) clk_reg,
                                                   >> 347                                     sizeof(clk_reg)) == -1) {
                                                   >> 348                         prom_printf("clock_probe: FAILED!\n");
                                                   >> 349                         prom_halt();
                                                   >> 350                 }
                                                   >> 351                 if (sparc_cpu_model == sun4d)
                                                   >> 352                         prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
                                                   >> 353                 else
                                                   >> 354                         prom_apply_obio_ranges(clk_reg, 1);
                                                   >> 355                 /* Map the clock register io area read-only */
                                                   >> 356                 /* XXX r/o attribute is somewhere in r.flags */
                                                   >> 357                 r.flags = clk_reg[0].which_io;
                                                   >> 358                 r.start = clk_reg[0].phys_addr;
                                                   >> 359                 mstk48t08_regs = (struct mostek48t08 *) sbus_ioremap(&r, 0,
                                                   >> 360                     sizeof(struct mostek48t08), "mk48t08");
                                                   >> 361 
                                                   >> 362                 mstk48t02_regs = (unsigned long)&mstk48t08_regs->regs;
 35         } else {                                  363         } else {
 36                 status = acpi_get_table(ACPI_S !! 364                 prom_printf("CLOCK: Unknown model name '%s'\n",model);
 37                 if (ACPI_FAILURE(status))      !! 365                 prom_halt();
 38                         panic("RISC-V ACPI sys !! 366         }
                                                   >> 367 
                                                   >> 368         /* Report a low battery voltage condition. */
                                                   >> 369         if (has_low_battery())
                                                   >> 370                 printk(KERN_CRIT "NVRAM: Low battery voltage!\n");
                                                   >> 371 
                                                   >> 372         /* Kick start the clock if it is completely stopped. */
                                                   >> 373         if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
                                                   >> 374                 kick_start_clock();
                                                   >> 375 }
                                                   >> 376 
                                                   >> 377 void __init sbus_time_init(void)
                                                   >> 378 {
                                                   >> 379         unsigned int year, mon, day, hour, min, sec;
                                                   >> 380         struct mostek48t02 *mregs;
                                                   >> 381 
                                                   >> 382 #ifdef CONFIG_SUN4
                                                   >> 383         int temp;
                                                   >> 384         struct intersil *iregs;
                                                   >> 385 #endif
                                                   >> 386 
                                                   >> 387         BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
                                                   >> 388         btfixup();
                                                   >> 389 
                                                   >> 390         if (ARCH_SUN4)
                                                   >> 391                 sun4_clock_probe();
                                                   >> 392         else
                                                   >> 393                 clock_probe();
                                                   >> 394 
                                                   >> 395         sparc_init_timers(timer_interrupt);
                                                   >> 396         
                                                   >> 397 #ifdef CONFIG_SUN4
                                                   >> 398         if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) {
                                                   >> 399 #endif
                                                   >> 400         mregs = (struct mostek48t02 *)mstk48t02_regs;
                                                   >> 401         if(!mregs) {
                                                   >> 402                 prom_printf("Something wrong, clock regs not mapped yet.\n");
                                                   >> 403                 prom_halt();
                                                   >> 404         }               
                                                   >> 405         spin_lock_irq(&mostek_lock);
                                                   >> 406         mregs->creg |= MSTK_CREG_READ;
                                                   >> 407         sec = MSTK_REG_SEC(mregs);
                                                   >> 408         min = MSTK_REG_MIN(mregs);
                                                   >> 409         hour = MSTK_REG_HOUR(mregs);
                                                   >> 410         day = MSTK_REG_DOM(mregs);
                                                   >> 411         mon = MSTK_REG_MONTH(mregs);
                                                   >> 412         year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
                                                   >> 413         xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
                                                   >> 414         xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
                                                   >> 415         set_normalized_timespec(&wall_to_monotonic,
                                                   >> 416                                 -xtime.tv_sec, -xtime.tv_nsec);
                                                   >> 417         mregs->creg &= ~MSTK_CREG_READ;
                                                   >> 418         spin_unlock_irq(&mostek_lock);
                                                   >> 419 #ifdef CONFIG_SUN4
                                                   >> 420         } else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) {
                                                   >> 421                 /* initialise the intersil on sun4 */
                                                   >> 422 
                                                   >> 423                 iregs=intersil_clock;
                                                   >> 424                 if(!iregs) {
                                                   >> 425                         prom_printf("Something wrong, clock regs not mapped yet.\n");
                                                   >> 426                         prom_halt();
                                                   >> 427                 }
                                                   >> 428 
                                                   >> 429                 intersil_intr(intersil_clock,INTERSIL_INT_100HZ);
                                                   >> 430                 disable_pil_irq(10);
                                                   >> 431                 intersil_stop(iregs);
                                                   >> 432                 intersil_read_intr(intersil_clock, temp);
                                                   >> 433 
                                                   >> 434                 temp = iregs->clk.int_csec;
                                                   >> 435 
                                                   >> 436                 sec = iregs->clk.int_sec;
                                                   >> 437                 min = iregs->clk.int_min;
                                                   >> 438                 hour = iregs->clk.int_hour;
                                                   >> 439                 day = iregs->clk.int_day;
                                                   >> 440                 mon = iregs->clk.int_month;
                                                   >> 441                 year = MSTK_CVT_YEAR(iregs->clk.int_year);
                                                   >> 442 
                                                   >> 443                 enable_pil_irq(10);
                                                   >> 444                 intersil_start(iregs);
                                                   >> 445 
                                                   >> 446                 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
                                                   >> 447                 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
                                                   >> 448                 set_normalized_timespec(&wall_to_monotonic,
                                                   >> 449                                        -xtime.tv_sec, -xtime.tv_nsec);
                                                   >> 450                 printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec);
                                                   >> 451         }
                                                   >> 452 #endif
                                                   >> 453 
                                                   >> 454         /* Now that OBP ticker has been silenced, it is safe to enable IRQ. */
                                                   >> 455         local_irq_enable();
                                                   >> 456 }
                                                   >> 457 
                                                   >> 458 void __init time_init(void)
                                                   >> 459 {
                                                   >> 460 #ifdef CONFIG_PCI
                                                   >> 461         extern void pci_time_init(void);
                                                   >> 462         if (pcic_present()) {
                                                   >> 463                 pci_time_init();
                                                   >> 464                 return;
                                                   >> 465         }
                                                   >> 466 #endif
                                                   >> 467         sbus_time_init();
                                                   >> 468 }
                                                   >> 469 
                                                   >> 470 extern __inline__ unsigned long do_gettimeoffset(void)
                                                   >> 471 {
                                                   >> 472         return (*master_l10_counter >> 10) & 0x1fffff;
                                                   >> 473 }
                                                   >> 474 
                                                   >> 475 /*
                                                   >> 476  * Returns nanoseconds
                                                   >> 477  * XXX This is a suboptimal implementation.
                                                   >> 478  */
                                                   >> 479 unsigned long long sched_clock(void)
                                                   >> 480 {
                                                   >> 481         return (unsigned long long)jiffies * (1000000000 / HZ);
                                                   >> 482 }
 39                                                   483 
 40                 riscv_timebase = rhct->time_ba !! 484 /* Ok, my cute asm atomicity trick doesn't work anymore.
 41                 acpi_put_table((struct acpi_ta !! 485  * There are just too many variables that need to be protected
                                                   >> 486  * now (both members of xtime, wall_jiffies, et al.)
                                                   >> 487  */
                                                   >> 488 void do_gettimeofday(struct timeval *tv)
                                                   >> 489 {
                                                   >> 490         unsigned long flags;
                                                   >> 491         unsigned long seq;
                                                   >> 492         unsigned long usec, sec;
                                                   >> 493         unsigned long max_ntp_tick = tick_usec - tickadj;
                                                   >> 494 
                                                   >> 495         do {
                                                   >> 496                 unsigned long lost;
                                                   >> 497 
                                                   >> 498                 seq = read_seqbegin_irqsave(&xtime_lock, flags);
                                                   >> 499                 usec = do_gettimeoffset();
                                                   >> 500                 lost = jiffies - wall_jiffies;
                                                   >> 501 
                                                   >> 502                 /*
                                                   >> 503                  * If time_adjust is negative then NTP is slowing the clock
                                                   >> 504                  * so make sure not to go into next possible interval.
                                                   >> 505                  * Better to lose some accuracy than have time go backwards..
                                                   >> 506                  */
                                                   >> 507                 if (unlikely(time_adjust < 0)) {
                                                   >> 508                         usec = min(usec, max_ntp_tick);
                                                   >> 509 
                                                   >> 510                         if (lost)
                                                   >> 511                                 usec += lost * max_ntp_tick;
                                                   >> 512                 }
                                                   >> 513                 else if (unlikely(lost))
                                                   >> 514                         usec += lost * tick_usec;
                                                   >> 515 
                                                   >> 516                 sec = xtime.tv_sec;
                                                   >> 517                 usec += (xtime.tv_nsec / 1000);
                                                   >> 518         } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
                                                   >> 519 
                                                   >> 520         while (usec >= 1000000) {
                                                   >> 521                 usec -= 1000000;
                                                   >> 522                 sec++;
 42         }                                         523         }
 43                                                   524 
 44         lpj_fine = riscv_timebase / HZ;        !! 525         tv->tv_sec = sec;
                                                   >> 526         tv->tv_usec = usec;
                                                   >> 527 }
                                                   >> 528 
                                                   >> 529 EXPORT_SYMBOL(do_gettimeofday);
                                                   >> 530 
                                                   >> 531 int do_settimeofday(struct timespec *tv)
                                                   >> 532 {
                                                   >> 533         int ret;
                                                   >> 534 
                                                   >> 535         write_seqlock_irq(&xtime_lock);
                                                   >> 536         ret = bus_do_settimeofday(tv);
                                                   >> 537         write_sequnlock_irq(&xtime_lock);
                                                   >> 538         return ret;
                                                   >> 539 }
                                                   >> 540 
                                                   >> 541 EXPORT_SYMBOL(do_settimeofday);
                                                   >> 542 
                                                   >> 543 static int sbus_do_settimeofday(struct timespec *tv)
                                                   >> 544 {
                                                   >> 545         time_t wtm_sec, sec = tv->tv_sec;
                                                   >> 546         long wtm_nsec, nsec = tv->tv_nsec;
                                                   >> 547 
                                                   >> 548         if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
                                                   >> 549                 return -EINVAL;
 45                                                   550 
 46         timer_probe();                         !! 551         /*
                                                   >> 552          * This is revolting. We need to set "xtime" correctly. However, the
                                                   >> 553          * value in this location is the value at the most recent update of
                                                   >> 554          * wall time.  Discover what correction gettimeofday() would have
                                                   >> 555          * made, and then undo it!
                                                   >> 556          */
                                                   >> 557         nsec -= 1000 * (do_gettimeoffset() +
                                                   >> 558                         (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
 47                                                   559 
 48         tick_setup_hrtimer_broadcast();        !! 560         wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
                                                   >> 561         wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
 49                                                   562 
 50         pv_time_init();                        !! 563         set_normalized_timespec(&xtime, sec, nsec);
                                                   >> 564         set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
                                                   >> 565 
                                                   >> 566         time_adjust = 0;                /* stop active adjtime() */
                                                   >> 567         time_status |= STA_UNSYNC;
                                                   >> 568         time_maxerror = NTP_PHASE_LIMIT;
                                                   >> 569         time_esterror = NTP_PHASE_LIMIT;
                                                   >> 570         return 0;
                                                   >> 571 }
                                                   >> 572 
                                                   >> 573 /*
                                                   >> 574  * BUG: This routine does not handle hour overflow properly; it just
                                                   >> 575  *      sets the minutes. Usually you won't notice until after reboot!
                                                   >> 576  */
                                                   >> 577 static int set_rtc_mmss(unsigned long nowtime)
                                                   >> 578 {
                                                   >> 579         int real_seconds, real_minutes, mostek_minutes;
                                                   >> 580         struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
                                                   >> 581         unsigned long flags;
                                                   >> 582 #ifdef CONFIG_SUN4
                                                   >> 583         struct intersil *iregs = intersil_clock;
                                                   >> 584         int temp;
                                                   >> 585 #endif
                                                   >> 586 
                                                   >> 587         /* Not having a register set can lead to trouble. */
                                                   >> 588         if (!regs) {
                                                   >> 589 #ifdef CONFIG_SUN4
                                                   >> 590                 if(!iregs)
                                                   >> 591                 return -1;
                                                   >> 592                 else {
                                                   >> 593                         temp = iregs->clk.int_csec;
                                                   >> 594 
                                                   >> 595                         mostek_minutes = iregs->clk.int_min;
                                                   >> 596 
                                                   >> 597                         real_seconds = nowtime % 60;
                                                   >> 598                         real_minutes = nowtime / 60;
                                                   >> 599                         if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
                                                   >> 600                                 real_minutes += 30;     /* correct for half hour time zone */
                                                   >> 601                         real_minutes %= 60;
                                                   >> 602 
                                                   >> 603                         if (abs(real_minutes - mostek_minutes) < 30) {
                                                   >> 604                                 intersil_stop(iregs);
                                                   >> 605                                 iregs->clk.int_sec=real_seconds;
                                                   >> 606                                 iregs->clk.int_min=real_minutes;
                                                   >> 607                                 intersil_start(iregs);
                                                   >> 608                         } else {
                                                   >> 609                                 printk(KERN_WARNING
                                                   >> 610                                "set_rtc_mmss: can't update from %d to %d\n",
                                                   >> 611                                        mostek_minutes, real_minutes);
                                                   >> 612                                 return -1;
                                                   >> 613                         }
                                                   >> 614                         
                                                   >> 615                         return 0;
                                                   >> 616                 }
                                                   >> 617 #endif
                                                   >> 618         }
                                                   >> 619 
                                                   >> 620         spin_lock_irqsave(&mostek_lock, flags);
                                                   >> 621         /* Read the current RTC minutes. */
                                                   >> 622         regs->creg |= MSTK_CREG_READ;
                                                   >> 623         mostek_minutes = MSTK_REG_MIN(regs);
                                                   >> 624         regs->creg &= ~MSTK_CREG_READ;
                                                   >> 625 
                                                   >> 626         /*
                                                   >> 627          * since we're only adjusting minutes and seconds,
                                                   >> 628          * don't interfere with hour overflow. This avoids
                                                   >> 629          * messing with unknown time zones but requires your
                                                   >> 630          * RTC not to be off by more than 15 minutes
                                                   >> 631          */
                                                   >> 632         real_seconds = nowtime % 60;
                                                   >> 633         real_minutes = nowtime / 60;
                                                   >> 634         if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
                                                   >> 635                 real_minutes += 30;     /* correct for half hour time zone */
                                                   >> 636         real_minutes %= 60;
                                                   >> 637 
                                                   >> 638         if (abs(real_minutes - mostek_minutes) < 30) {
                                                   >> 639                 regs->creg |= MSTK_CREG_WRITE;
                                                   >> 640                 MSTK_SET_REG_SEC(regs,real_seconds);
                                                   >> 641                 MSTK_SET_REG_MIN(regs,real_minutes);
                                                   >> 642                 regs->creg &= ~MSTK_CREG_WRITE;
                                                   >> 643                 spin_unlock_irqrestore(&mostek_lock, flags);
                                                   >> 644                 return 0;
                                                   >> 645         } else {
                                                   >> 646                 spin_unlock_irqrestore(&mostek_lock, flags);
                                                   >> 647                 return -1;
                                                   >> 648         }
 51 }                                                 649 }
 52                                                   650 

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