linux/arch/x86/kernel/rtc.c
<<
>>
Prefs
   1/*
   2 * RTC related functions
   3 */
   4#include <linux/platform_device.h>
   5#include <linux/mc146818rtc.h>
   6#include <linux/acpi.h>
   7#include <linux/bcd.h>
   8#include <linux/export.h>
   9#include <linux/pnp.h>
  10#include <linux/of.h>
  11
  12#include <asm/vsyscall.h>
  13#include <asm/x86_init.h>
  14#include <asm/time.h>
  15#include <asm/mrst.h>
  16#include <asm/rtc.h>
  17
  18#ifdef CONFIG_X86_32
  19/*
  20 * This is a special lock that is owned by the CPU and holds the index
  21 * register we are working with.  It is required for NMI access to the
  22 * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
  23 */
  24volatile unsigned long cmos_lock;
  25EXPORT_SYMBOL(cmos_lock);
  26#endif /* CONFIG_X86_32 */
  27
  28/* For two digit years assume time is always after that */
  29#define CMOS_YEARS_OFFS 2000
  30
  31DEFINE_SPINLOCK(rtc_lock);
  32EXPORT_SYMBOL(rtc_lock);
  33
  34/*
  35 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
  36 * called 500 ms after the second nowtime has started, because when
  37 * nowtime is written into the registers of the CMOS clock, it will
  38 * jump to the next second precisely 500 ms later. Check the Motorola
  39 * MC146818A or Dallas DS12887 data sheet for details.
  40 */
  41int mach_set_rtc_mmss(unsigned long nowtime)
  42{
  43        struct rtc_time tm;
  44        int retval = 0;
  45
  46        rtc_time_to_tm(nowtime, &tm);
  47        if (!rtc_valid_tm(&tm)) {
  48                retval = set_rtc_time(&tm);
  49                if (retval)
  50                        printk(KERN_ERR "%s: RTC write failed with error %d\n",
  51                               __FUNCTION__, retval);
  52        } else {
  53                printk(KERN_ERR
  54                       "%s: Invalid RTC value: write of %lx to RTC failed\n",
  55                        __FUNCTION__, nowtime);
  56                retval = -EINVAL;
  57        }
  58        return retval;
  59}
  60
  61unsigned long mach_get_cmos_time(void)
  62{
  63        unsigned int status, year, mon, day, hour, min, sec, century = 0;
  64        unsigned long flags;
  65
  66        spin_lock_irqsave(&rtc_lock, flags);
  67
  68        /*
  69         * If UIP is clear, then we have >= 244 microseconds before
  70         * RTC registers will be updated.  Spec sheet says that this
  71         * is the reliable way to read RTC - registers. If UIP is set
  72         * then the register access might be invalid.
  73         */
  74        while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
  75                cpu_relax();
  76
  77        sec = CMOS_READ(RTC_SECONDS);
  78        min = CMOS_READ(RTC_MINUTES);
  79        hour = CMOS_READ(RTC_HOURS);
  80        day = CMOS_READ(RTC_DAY_OF_MONTH);
  81        mon = CMOS_READ(RTC_MONTH);
  82        year = CMOS_READ(RTC_YEAR);
  83
  84#ifdef CONFIG_ACPI
  85        if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
  86            acpi_gbl_FADT.century)
  87                century = CMOS_READ(acpi_gbl_FADT.century);
  88#endif
  89
  90        status = CMOS_READ(RTC_CONTROL);
  91        WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY));
  92
  93        spin_unlock_irqrestore(&rtc_lock, flags);
  94
  95        if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) {
  96                sec = bcd2bin(sec);
  97                min = bcd2bin(min);
  98                hour = bcd2bin(hour);
  99                day = bcd2bin(day);
 100                mon = bcd2bin(mon);
 101                year = bcd2bin(year);
 102        }
 103
 104        if (century) {
 105                century = bcd2bin(century);
 106                year += century * 100;
 107        } else
 108                year += CMOS_YEARS_OFFS;
 109
 110        return mktime(year, mon, day, hour, min, sec);
 111}
 112
 113/* Routines for accessing the CMOS RAM/RTC. */
 114unsigned char rtc_cmos_read(unsigned char addr)
 115{
 116        unsigned char val;
 117
 118        lock_cmos_prefix(addr);
 119        outb(addr, RTC_PORT(0));
 120        val = inb(RTC_PORT(1));
 121        lock_cmos_suffix(addr);
 122
 123        return val;
 124}
 125EXPORT_SYMBOL(rtc_cmos_read);
 126
 127void rtc_cmos_write(unsigned char val, unsigned char addr)
 128{
 129        lock_cmos_prefix(addr);
 130        outb(addr, RTC_PORT(0));
 131        outb(val, RTC_PORT(1));
 132        lock_cmos_suffix(addr);
 133}
 134EXPORT_SYMBOL(rtc_cmos_write);
 135
 136int update_persistent_clock(struct timespec now)
 137{
 138        return x86_platform.set_wallclock(now.tv_sec);
 139}
 140
 141/* not static: needed by APM */
 142void read_persistent_clock(struct timespec *ts)
 143{
 144        unsigned long retval;
 145
 146        retval = x86_platform.get_wallclock();
 147
 148        ts->tv_sec = retval;
 149        ts->tv_nsec = 0;
 150}
 151
 152
 153static struct resource rtc_resources[] = {
 154        [0] = {
 155                .start  = RTC_PORT(0),
 156                .end    = RTC_PORT(1),
 157                .flags  = IORESOURCE_IO,
 158        },
 159        [1] = {
 160                .start  = RTC_IRQ,
 161                .end    = RTC_IRQ,
 162                .flags  = IORESOURCE_IRQ,
 163        }
 164};
 165
 166static struct platform_device rtc_device = {
 167        .name           = "rtc_cmos",
 168        .id             = -1,
 169        .resource       = rtc_resources,
 170        .num_resources  = ARRAY_SIZE(rtc_resources),
 171};
 172
 173static __init int add_rtc_cmos(void)
 174{
 175#ifdef CONFIG_PNP
 176        static const char * const  const ids[] __initconst =
 177            { "PNP0b00", "PNP0b01", "PNP0b02", };
 178        struct pnp_dev *dev;
 179        struct pnp_id *id;
 180        int i;
 181
 182        pnp_for_each_dev(dev) {
 183                for (id = dev->id; id; id = id->next) {
 184                        for (i = 0; i < ARRAY_SIZE(ids); i++) {
 185                                if (compare_pnp_id(id, ids[i]) != 0)
 186                                        return 0;
 187                        }
 188                }
 189        }
 190#endif
 191        if (of_have_populated_dt())
 192                return 0;
 193
 194        /* Intel MID platforms don't have ioport rtc */
 195        if (mrst_identify_cpu())
 196                return -ENODEV;
 197
 198        platform_device_register(&rtc_device);
 199        dev_info(&rtc_device.dev,
 200                 "registered platform RTC device (no PNP device found)\n");
 201
 202        return 0;
 203}
 204device_initcall(add_rtc_cmos);
 205