Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * RTC related functions
0004  */
0005 #include <linux/platform_device.h>
0006 #include <linux/mc146818rtc.h>
0007 #include <linux/acpi.h>
0008 #include <linux/bcd.h>
0009 #include <linux/export.h>
0010 #include <linux/pnp.h>
0011 #include <linux/of.h>
0012 
0013 #include <asm/vsyscall.h>
0014 #include <asm/x86_init.h>
0015 #include <asm/time.h>
0016 #include <asm/intel-mid.h>
0017 #include <asm/setup.h>
0018 
0019 #ifdef CONFIG_X86_32
0020 /*
0021  * This is a special lock that is owned by the CPU and holds the index
0022  * register we are working with.  It is required for NMI access to the
0023  * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
0024  */
0025 volatile unsigned long cmos_lock;
0026 EXPORT_SYMBOL(cmos_lock);
0027 #endif /* CONFIG_X86_32 */
0028 
0029 /* For two digit years assume time is always after that */
0030 #define CMOS_YEARS_OFFS 2000
0031 
0032 DEFINE_SPINLOCK(rtc_lock);
0033 EXPORT_SYMBOL(rtc_lock);
0034 
0035 /*
0036  * In order to set the CMOS clock precisely, set_rtc_mmss has to be
0037  * called 500 ms after the second nowtime has started, because when
0038  * nowtime is written into the registers of the CMOS clock, it will
0039  * jump to the next second precisely 500 ms later. Check the Motorola
0040  * MC146818A or Dallas DS12887 data sheet for details.
0041  */
0042 int mach_set_rtc_mmss(const struct timespec64 *now)
0043 {
0044     unsigned long long nowtime = now->tv_sec;
0045     struct rtc_time tm;
0046     int retval = 0;
0047 
0048     rtc_time64_to_tm(nowtime, &tm);
0049     if (!rtc_valid_tm(&tm)) {
0050         retval = mc146818_set_time(&tm);
0051         if (retval)
0052             printk(KERN_ERR "%s: RTC write failed with error %d\n",
0053                    __func__, retval);
0054     } else {
0055         printk(KERN_ERR
0056                "%s: Invalid RTC value: write of %llx to RTC failed\n",
0057             __func__, nowtime);
0058         retval = -EINVAL;
0059     }
0060     return retval;
0061 }
0062 
0063 void mach_get_cmos_time(struct timespec64 *now)
0064 {
0065     unsigned int status, year, mon, day, hour, min, sec, century = 0;
0066     unsigned long flags;
0067 
0068     /*
0069      * If pm_trace abused the RTC as storage, set the timespec to 0,
0070      * which tells the caller that this RTC value is unusable.
0071      */
0072     if (!pm_trace_rtc_valid()) {
0073         now->tv_sec = now->tv_nsec = 0;
0074         return;
0075     }
0076 
0077     spin_lock_irqsave(&rtc_lock, flags);
0078 
0079     /*
0080      * If UIP is clear, then we have >= 244 microseconds before
0081      * RTC registers will be updated.  Spec sheet says that this
0082      * is the reliable way to read RTC - registers. If UIP is set
0083      * then the register access might be invalid.
0084      */
0085     while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
0086         cpu_relax();
0087 
0088     sec = CMOS_READ(RTC_SECONDS);
0089     min = CMOS_READ(RTC_MINUTES);
0090     hour = CMOS_READ(RTC_HOURS);
0091     day = CMOS_READ(RTC_DAY_OF_MONTH);
0092     mon = CMOS_READ(RTC_MONTH);
0093     year = CMOS_READ(RTC_YEAR);
0094 
0095 #ifdef CONFIG_ACPI
0096     if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
0097         acpi_gbl_FADT.century)
0098         century = CMOS_READ(acpi_gbl_FADT.century);
0099 #endif
0100 
0101     status = CMOS_READ(RTC_CONTROL);
0102     WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY));
0103 
0104     spin_unlock_irqrestore(&rtc_lock, flags);
0105 
0106     if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) {
0107         sec = bcd2bin(sec);
0108         min = bcd2bin(min);
0109         hour = bcd2bin(hour);
0110         day = bcd2bin(day);
0111         mon = bcd2bin(mon);
0112         year = bcd2bin(year);
0113     }
0114 
0115     if (century) {
0116         century = bcd2bin(century);
0117         year += century * 100;
0118     } else
0119         year += CMOS_YEARS_OFFS;
0120 
0121     now->tv_sec = mktime64(year, mon, day, hour, min, sec);
0122     now->tv_nsec = 0;
0123 }
0124 
0125 /* Routines for accessing the CMOS RAM/RTC. */
0126 unsigned char rtc_cmos_read(unsigned char addr)
0127 {
0128     unsigned char val;
0129 
0130     lock_cmos_prefix(addr);
0131     outb(addr, RTC_PORT(0));
0132     val = inb(RTC_PORT(1));
0133     lock_cmos_suffix(addr);
0134 
0135     return val;
0136 }
0137 EXPORT_SYMBOL(rtc_cmos_read);
0138 
0139 void rtc_cmos_write(unsigned char val, unsigned char addr)
0140 {
0141     lock_cmos_prefix(addr);
0142     outb(addr, RTC_PORT(0));
0143     outb(val, RTC_PORT(1));
0144     lock_cmos_suffix(addr);
0145 }
0146 EXPORT_SYMBOL(rtc_cmos_write);
0147 
0148 int update_persistent_clock64(struct timespec64 now)
0149 {
0150     return x86_platform.set_wallclock(&now);
0151 }
0152 
0153 /* not static: needed by APM */
0154 void read_persistent_clock64(struct timespec64 *ts)
0155 {
0156     x86_platform.get_wallclock(ts);
0157 }
0158 
0159 
0160 static struct resource rtc_resources[] = {
0161     [0] = {
0162         .start  = RTC_PORT(0),
0163         .end    = RTC_PORT(1),
0164         .flags  = IORESOURCE_IO,
0165     },
0166     [1] = {
0167         .start  = RTC_IRQ,
0168         .end    = RTC_IRQ,
0169         .flags  = IORESOURCE_IRQ,
0170     }
0171 };
0172 
0173 static struct platform_device rtc_device = {
0174     .name       = "rtc_cmos",
0175     .id     = -1,
0176     .resource   = rtc_resources,
0177     .num_resources  = ARRAY_SIZE(rtc_resources),
0178 };
0179 
0180 static __init int add_rtc_cmos(void)
0181 {
0182 #ifdef CONFIG_PNP
0183     static const char * const ids[] __initconst =
0184         { "PNP0b00", "PNP0b01", "PNP0b02", };
0185     struct pnp_dev *dev;
0186     struct pnp_id *id;
0187     int i;
0188 
0189     pnp_for_each_dev(dev) {
0190         for (id = dev->id; id; id = id->next) {
0191             for (i = 0; i < ARRAY_SIZE(ids); i++) {
0192                 if (compare_pnp_id(id, ids[i]) != 0)
0193                     return 0;
0194             }
0195         }
0196     }
0197 #endif
0198     if (!x86_platform.legacy.rtc)
0199         return -ENODEV;
0200 
0201     platform_device_register(&rtc_device);
0202     dev_info(&rtc_device.dev,
0203          "registered platform RTC device (no PNP device found)\n");
0204 
0205     return 0;
0206 }
0207 device_initcall(add_rtc_cmos);