root/arch/alpha/kernel/rtc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. specifiy_epoch
  2. init_rtc_epoch
  3. alpha_rtc_read_time
  4. alpha_rtc_set_time
  5. alpha_rtc_ioctl
  6. do_remote_read
  7. remote_read_time
  8. do_remote_set
  9. remote_set_time
  10. alpha_rtc_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  linux/arch/alpha/kernel/rtc.c
   4  *
   5  *  Copyright (C) 1991, 1992, 1995, 1999, 2000  Linus Torvalds
   6  *
   7  * This file contains date handling.
   8  */
   9 #include <linux/errno.h>
  10 #include <linux/init.h>
  11 #include <linux/kernel.h>
  12 #include <linux/param.h>
  13 #include <linux/string.h>
  14 #include <linux/mc146818rtc.h>
  15 #include <linux/bcd.h>
  16 #include <linux/rtc.h>
  17 #include <linux/platform_device.h>
  18 
  19 #include "proto.h"
  20 
  21 
  22 /*
  23  * Support for the RTC device.
  24  *
  25  * We don't want to use the rtc-cmos driver, because we don't want to support
  26  * alarms, as that would be indistinguishable from timer interrupts.
  27  *
  28  * Further, generic code is really, really tied to a 1900 epoch.  This is
  29  * true in __get_rtc_time as well as the users of struct rtc_time e.g.
  30  * rtc_tm_to_time.  Thankfully all of the other epochs in use are later
  31  * than 1900, and so it's easy to adjust.
  32  */
  33 
  34 static unsigned long rtc_epoch;
  35 
  36 static int __init
  37 specifiy_epoch(char *str)
  38 {
  39         unsigned long epoch = simple_strtoul(str, NULL, 0);
  40         if (epoch < 1900)
  41                 printk("Ignoring invalid user specified epoch %lu\n", epoch);
  42         else
  43                 rtc_epoch = epoch;
  44         return 1;
  45 }
  46 __setup("epoch=", specifiy_epoch);
  47 
  48 static void __init
  49 init_rtc_epoch(void)
  50 {
  51         int epoch, year, ctrl;
  52 
  53         if (rtc_epoch != 0) {
  54                 /* The epoch was specified on the command-line.  */
  55                 return;
  56         }
  57 
  58         /* Detect the epoch in use on this computer.  */
  59         ctrl = CMOS_READ(RTC_CONTROL);
  60         year = CMOS_READ(RTC_YEAR);
  61         if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
  62                 year = bcd2bin(year);
  63 
  64         /* PC-like is standard; used for year >= 70 */
  65         epoch = 1900;
  66         if (year < 20) {
  67                 epoch = 2000;
  68         } else if (year >= 20 && year < 48) {
  69                 /* NT epoch */
  70                 epoch = 1980;
  71         } else if (year >= 48 && year < 70) {
  72                 /* Digital UNIX epoch */
  73                 epoch = 1952;
  74         }
  75         rtc_epoch = epoch;
  76 
  77         printk(KERN_INFO "Using epoch %d for rtc year %d\n", epoch, year);
  78 }
  79 
  80 static int
  81 alpha_rtc_read_time(struct device *dev, struct rtc_time *tm)
  82 {
  83         mc146818_get_time(tm);
  84 
  85         /* Adjust for non-default epochs.  It's easier to depend on the
  86            generic __get_rtc_time and adjust the epoch here than create
  87            a copy of __get_rtc_time with the edits we need.  */
  88         if (rtc_epoch != 1900) {
  89                 int year = tm->tm_year;
  90                 /* Undo the century adjustment made in __get_rtc_time.  */
  91                 if (year >= 100)
  92                         year -= 100;
  93                 year += rtc_epoch - 1900;
  94                 /* Redo the century adjustment with the epoch in place.  */
  95                 if (year <= 69)
  96                         year += 100;
  97                 tm->tm_year = year;
  98         }
  99 
 100         return 0;
 101 }
 102 
 103 static int
 104 alpha_rtc_set_time(struct device *dev, struct rtc_time *tm)
 105 {
 106         struct rtc_time xtm;
 107 
 108         if (rtc_epoch != 1900) {
 109                 xtm = *tm;
 110                 xtm.tm_year -= rtc_epoch - 1900;
 111                 tm = &xtm;
 112         }
 113 
 114         return mc146818_set_time(tm);
 115 }
 116 
 117 static int
 118 alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 119 {
 120         switch (cmd) {
 121         case RTC_EPOCH_READ:
 122                 return put_user(rtc_epoch, (unsigned long __user *)arg);
 123         case RTC_EPOCH_SET:
 124                 if (arg < 1900)
 125                         return -EINVAL;
 126                 rtc_epoch = arg;
 127                 return 0;
 128         default:
 129                 return -ENOIOCTLCMD;
 130         }
 131 }
 132 
 133 static const struct rtc_class_ops alpha_rtc_ops = {
 134         .read_time = alpha_rtc_read_time,
 135         .set_time = alpha_rtc_set_time,
 136         .ioctl = alpha_rtc_ioctl,
 137 };
 138 
 139 /*
 140  * Similarly, except do the actual CMOS access on the boot cpu only.
 141  * This requires marshalling the data across an interprocessor call.
 142  */
 143 
 144 #if defined(CONFIG_SMP) && \
 145     (defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_MARVEL))
 146 # define HAVE_REMOTE_RTC 1
 147 
 148 union remote_data {
 149         struct rtc_time *tm;
 150         long retval;
 151 };
 152 
 153 static void
 154 do_remote_read(void *data)
 155 {
 156         union remote_data *x = data;
 157         x->retval = alpha_rtc_read_time(NULL, x->tm);
 158 }
 159 
 160 static int
 161 remote_read_time(struct device *dev, struct rtc_time *tm)
 162 {
 163         union remote_data x;
 164         if (smp_processor_id() != boot_cpuid) {
 165                 x.tm = tm;
 166                 smp_call_function_single(boot_cpuid, do_remote_read, &x, 1);
 167                 return x.retval;
 168         }
 169         return alpha_rtc_read_time(NULL, tm);
 170 }
 171 
 172 static void
 173 do_remote_set(void *data)
 174 {
 175         union remote_data *x = data;
 176         x->retval = alpha_rtc_set_time(NULL, x->tm);
 177 }
 178 
 179 static int
 180 remote_set_time(struct device *dev, struct rtc_time *tm)
 181 {
 182         union remote_data x;
 183         if (smp_processor_id() != boot_cpuid) {
 184                 x.tm = tm;
 185                 smp_call_function_single(boot_cpuid, do_remote_set, &x, 1);
 186                 return x.retval;
 187         }
 188         return alpha_rtc_set_time(NULL, tm);
 189 }
 190 
 191 static const struct rtc_class_ops remote_rtc_ops = {
 192         .read_time = remote_read_time,
 193         .set_time = remote_set_time,
 194         .ioctl = alpha_rtc_ioctl,
 195 };
 196 #endif
 197 
 198 static int __init
 199 alpha_rtc_init(void)
 200 {
 201         struct platform_device *pdev;
 202         struct rtc_device *rtc;
 203 
 204         init_rtc_epoch();
 205 
 206         pdev = platform_device_register_simple("rtc-alpha", -1, NULL, 0);
 207         rtc = devm_rtc_allocate_device(&pdev->dev);
 208         if (IS_ERR(rtc))
 209                 return PTR_ERR(rtc);
 210 
 211         platform_set_drvdata(pdev, rtc);
 212         rtc->ops = &alpha_rtc_ops;
 213 
 214 #ifdef HAVE_REMOTE_RTC
 215         if (alpha_mv.rtc_boot_cpu_only)
 216                 rtc->ops = &remote_rtc_ops;
 217 #endif
 218 
 219         return rtc_register_device(rtc);
 220 }
 221 device_initcall(alpha_rtc_init);

/* [<][>][^][v][top][bottom][index][help] */