linux/drivers/rtc/rtc-mrst.c
<<
>>
Prefs
   1/*
   2 * rtc-mrst.c: Driver for Moorestown virtual RTC
   3 *
   4 * (C) Copyright 2009 Intel Corporation
   5 * Author: Jacob Pan (jacob.jun.pan@intel.com)
   6 *         Feng Tang (feng.tang@intel.com)
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * as published by the Free Software Foundation; version 2
  11 * of the License.
  12 *
  13 * Note:
  14 * VRTC is emulated by system controller firmware, the real HW
  15 * RTC is located in the PMIC device. SCU FW shadows PMIC RTC
  16 * in a memory mapped IO space that is visible to the host IA
  17 * processor.
  18 *
  19 * This driver is based upon drivers/rtc/rtc-cmos.c
  20 */
  21
  22/*
  23 * Note:
  24 *  * vRTC only supports binary mode and 24H mode
  25 *  * vRTC only support PIE and AIE, no UIE, and its PIE only happens
  26 *    at 23:59:59pm everyday, no support for adjustable frequency
  27 *  * Alarm function is also limited to hr/min/sec.
  28 */
  29
  30#include <linux/mod_devicetable.h>
  31#include <linux/platform_device.h>
  32#include <linux/interrupt.h>
  33#include <linux/spinlock.h>
  34#include <linux/kernel.h>
  35#include <linux/mc146818rtc.h>
  36#include <linux/module.h>
  37#include <linux/init.h>
  38#include <linux/sfi.h>
  39
  40#include <asm/intel_scu_ipc.h>
  41#include <asm/intel-mid.h>
  42#include <asm/intel_mid_vrtc.h>
  43
  44struct mrst_rtc {
  45        struct rtc_device       *rtc;
  46        struct device           *dev;
  47        int                     irq;
  48
  49        u8                      enabled_wake;
  50        u8                      suspend_ctrl;
  51};
  52
  53static const char driver_name[] = "rtc_mrst";
  54
  55#define RTC_IRQMASK     (RTC_PF | RTC_AF)
  56
  57static inline int is_intr(u8 rtc_intr)
  58{
  59        if (!(rtc_intr & RTC_IRQF))
  60                return 0;
  61        return rtc_intr & RTC_IRQMASK;
  62}
  63
  64static inline unsigned char vrtc_is_updating(void)
  65{
  66        unsigned char uip;
  67        unsigned long flags;
  68
  69        spin_lock_irqsave(&rtc_lock, flags);
  70        uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP);
  71        spin_unlock_irqrestore(&rtc_lock, flags);
  72        return uip;
  73}
  74
  75/*
  76 * rtc_time's year contains the increment over 1900, but vRTC's YEAR
  77 * register can't be programmed to value larger than 0x64, so vRTC
  78 * driver chose to use 1972 (1970 is UNIX time start point) as the base,
  79 * and does the translation at read/write time.
  80 *
  81 * Why not just use 1970 as the offset? it's because using 1972 will
  82 * make it consistent in leap year setting for both vrtc and low-level
  83 * physical rtc devices. Then why not use 1960 as the offset? If we use
  84 * 1960, for a device's first use, its YEAR register is 0 and the system
  85 * year will be parsed as 1960 which is not a valid UNIX time and will
  86 * cause many applications to fail mysteriously.
  87 */
  88static int mrst_read_time(struct device *dev, struct rtc_time *time)
  89{
  90        unsigned long flags;
  91
  92        if (vrtc_is_updating())
  93                msleep(20);
  94
  95        spin_lock_irqsave(&rtc_lock, flags);
  96        time->tm_sec = vrtc_cmos_read(RTC_SECONDS);
  97        time->tm_min = vrtc_cmos_read(RTC_MINUTES);
  98        time->tm_hour = vrtc_cmos_read(RTC_HOURS);
  99        time->tm_mday = vrtc_cmos_read(RTC_DAY_OF_MONTH);
 100        time->tm_mon = vrtc_cmos_read(RTC_MONTH);
 101        time->tm_year = vrtc_cmos_read(RTC_YEAR);
 102        spin_unlock_irqrestore(&rtc_lock, flags);
 103
 104        /* Adjust for the 1972/1900 */
 105        time->tm_year += 72;
 106        time->tm_mon--;
 107        return 0;
 108}
 109
 110static int mrst_set_time(struct device *dev, struct rtc_time *time)
 111{
 112        int ret;
 113        unsigned long flags;
 114        unsigned char mon, day, hrs, min, sec;
 115        unsigned int yrs;
 116
 117        yrs = time->tm_year;
 118        mon = time->tm_mon + 1;   /* tm_mon starts at zero */
 119        day = time->tm_mday;
 120        hrs = time->tm_hour;
 121        min = time->tm_min;
 122        sec = time->tm_sec;
 123
 124        if (yrs < 72 || yrs > 172)
 125                return -EINVAL;
 126        yrs -= 72;
 127
 128        spin_lock_irqsave(&rtc_lock, flags);
 129
 130        vrtc_cmos_write(yrs, RTC_YEAR);
 131        vrtc_cmos_write(mon, RTC_MONTH);
 132        vrtc_cmos_write(day, RTC_DAY_OF_MONTH);
 133        vrtc_cmos_write(hrs, RTC_HOURS);
 134        vrtc_cmos_write(min, RTC_MINUTES);
 135        vrtc_cmos_write(sec, RTC_SECONDS);
 136
 137        spin_unlock_irqrestore(&rtc_lock, flags);
 138
 139        ret = intel_scu_ipc_simple_command(IPCMSG_VRTC, IPC_CMD_VRTC_SETTIME);
 140        return ret;
 141}
 142
 143static int mrst_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 144{
 145        struct mrst_rtc *mrst = dev_get_drvdata(dev);
 146        unsigned char rtc_control;
 147
 148        if (mrst->irq <= 0)
 149                return -EIO;
 150
 151        /* vRTC only supports binary mode */
 152        spin_lock_irq(&rtc_lock);
 153        t->time.tm_sec = vrtc_cmos_read(RTC_SECONDS_ALARM);
 154        t->time.tm_min = vrtc_cmos_read(RTC_MINUTES_ALARM);
 155        t->time.tm_hour = vrtc_cmos_read(RTC_HOURS_ALARM);
 156
 157        rtc_control = vrtc_cmos_read(RTC_CONTROL);
 158        spin_unlock_irq(&rtc_lock);
 159
 160        t->enabled = !!(rtc_control & RTC_AIE);
 161        t->pending = 0;
 162
 163        return 0;
 164}
 165
 166static void mrst_checkintr(struct mrst_rtc *mrst, unsigned char rtc_control)
 167{
 168        unsigned char   rtc_intr;
 169
 170        /*
 171         * NOTE after changing RTC_xIE bits we always read INTR_FLAGS;
 172         * allegedly some older rtcs need that to handle irqs properly
 173         */
 174        rtc_intr = vrtc_cmos_read(RTC_INTR_FLAGS);
 175        rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
 176        if (is_intr(rtc_intr))
 177                rtc_update_irq(mrst->rtc, 1, rtc_intr);
 178}
 179
 180static void mrst_irq_enable(struct mrst_rtc *mrst, unsigned char mask)
 181{
 182        unsigned char   rtc_control;
 183
 184        /*
 185         * Flush any pending IRQ status, notably for update irqs,
 186         * before we enable new IRQs
 187         */
 188        rtc_control = vrtc_cmos_read(RTC_CONTROL);
 189        mrst_checkintr(mrst, rtc_control);
 190
 191        rtc_control |= mask;
 192        vrtc_cmos_write(rtc_control, RTC_CONTROL);
 193
 194        mrst_checkintr(mrst, rtc_control);
 195}
 196
 197static void mrst_irq_disable(struct mrst_rtc *mrst, unsigned char mask)
 198{
 199        unsigned char   rtc_control;
 200
 201        rtc_control = vrtc_cmos_read(RTC_CONTROL);
 202        rtc_control &= ~mask;
 203        vrtc_cmos_write(rtc_control, RTC_CONTROL);
 204        mrst_checkintr(mrst, rtc_control);
 205}
 206
 207static int mrst_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 208{
 209        struct mrst_rtc *mrst = dev_get_drvdata(dev);
 210        unsigned char hrs, min, sec;
 211        int ret = 0;
 212
 213        if (!mrst->irq)
 214                return -EIO;
 215
 216        hrs = t->time.tm_hour;
 217        min = t->time.tm_min;
 218        sec = t->time.tm_sec;
 219
 220        spin_lock_irq(&rtc_lock);
 221        /* Next rtc irq must not be from previous alarm setting */
 222        mrst_irq_disable(mrst, RTC_AIE);
 223
 224        /* Update alarm */
 225        vrtc_cmos_write(hrs, RTC_HOURS_ALARM);
 226        vrtc_cmos_write(min, RTC_MINUTES_ALARM);
 227        vrtc_cmos_write(sec, RTC_SECONDS_ALARM);
 228
 229        spin_unlock_irq(&rtc_lock);
 230
 231        ret = intel_scu_ipc_simple_command(IPCMSG_VRTC, IPC_CMD_VRTC_SETALARM);
 232        if (ret)
 233                return ret;
 234
 235        spin_lock_irq(&rtc_lock);
 236        if (t->enabled)
 237                mrst_irq_enable(mrst, RTC_AIE);
 238
 239        spin_unlock_irq(&rtc_lock);
 240
 241        return 0;
 242}
 243
 244/* Currently, the vRTC doesn't support UIE ON/OFF */
 245static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 246{
 247        struct mrst_rtc *mrst = dev_get_drvdata(dev);
 248        unsigned long   flags;
 249
 250        spin_lock_irqsave(&rtc_lock, flags);
 251        if (enabled)
 252                mrst_irq_enable(mrst, RTC_AIE);
 253        else
 254                mrst_irq_disable(mrst, RTC_AIE);
 255        spin_unlock_irqrestore(&rtc_lock, flags);
 256        return 0;
 257}
 258
 259
 260#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
 261
 262static int mrst_procfs(struct device *dev, struct seq_file *seq)
 263{
 264        unsigned char   rtc_control;
 265
 266        spin_lock_irq(&rtc_lock);
 267        rtc_control = vrtc_cmos_read(RTC_CONTROL);
 268        spin_unlock_irq(&rtc_lock);
 269
 270        seq_printf(seq,
 271                   "periodic_IRQ\t: %s\n"
 272                   "alarm\t\t: %s\n"
 273                   "BCD\t\t: no\n"
 274                   "periodic_freq\t: daily (not adjustable)\n",
 275                   (rtc_control & RTC_PIE) ? "on" : "off",
 276                   (rtc_control & RTC_AIE) ? "on" : "off");
 277
 278        return 0;
 279}
 280
 281#else
 282#define mrst_procfs     NULL
 283#endif
 284
 285static const struct rtc_class_ops mrst_rtc_ops = {
 286        .read_time      = mrst_read_time,
 287        .set_time       = mrst_set_time,
 288        .read_alarm     = mrst_read_alarm,
 289        .set_alarm      = mrst_set_alarm,
 290        .proc           = mrst_procfs,
 291        .alarm_irq_enable = mrst_rtc_alarm_irq_enable,
 292};
 293
 294static struct mrst_rtc  mrst_rtc;
 295
 296/*
 297 * When vRTC IRQ is captured by SCU FW, FW will clear the AIE bit in
 298 * Reg B, so no need for this driver to clear it
 299 */
 300static irqreturn_t mrst_rtc_irq(int irq, void *p)
 301{
 302        u8 irqstat;
 303
 304        spin_lock(&rtc_lock);
 305        /* This read will clear all IRQ flags inside Reg C */
 306        irqstat = vrtc_cmos_read(RTC_INTR_FLAGS);
 307        spin_unlock(&rtc_lock);
 308
 309        irqstat &= RTC_IRQMASK | RTC_IRQF;
 310        if (is_intr(irqstat)) {
 311                rtc_update_irq(p, 1, irqstat);
 312                return IRQ_HANDLED;
 313        }
 314        return IRQ_NONE;
 315}
 316
 317static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem,
 318                              int rtc_irq)
 319{
 320        int retval = 0;
 321        unsigned char rtc_control;
 322
 323        /* There can be only one ... */
 324        if (mrst_rtc.dev)
 325                return -EBUSY;
 326
 327        if (!iomem)
 328                return -ENODEV;
 329
 330        iomem = devm_request_mem_region(dev, iomem->start, resource_size(iomem),
 331                                        driver_name);
 332        if (!iomem) {
 333                dev_dbg(dev, "i/o mem already in use.\n");
 334                return -EBUSY;
 335        }
 336
 337        mrst_rtc.irq = rtc_irq;
 338        mrst_rtc.dev = dev;
 339        dev_set_drvdata(dev, &mrst_rtc);
 340
 341        mrst_rtc.rtc = devm_rtc_allocate_device(dev);
 342        if (IS_ERR(mrst_rtc.rtc))
 343                return PTR_ERR(mrst_rtc.rtc);
 344
 345        mrst_rtc.rtc->ops = &mrst_rtc_ops;
 346
 347        rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));
 348
 349        spin_lock_irq(&rtc_lock);
 350        mrst_irq_disable(&mrst_rtc, RTC_PIE | RTC_AIE);
 351        rtc_control = vrtc_cmos_read(RTC_CONTROL);
 352        spin_unlock_irq(&rtc_lock);
 353
 354        if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))
 355                dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n");
 356
 357        if (rtc_irq) {
 358                retval = devm_request_irq(dev, rtc_irq, mrst_rtc_irq,
 359                                          0, dev_name(&mrst_rtc.rtc->dev),
 360                                          mrst_rtc.rtc);
 361                if (retval < 0) {
 362                        dev_dbg(dev, "IRQ %d is already in use, err %d\n",
 363                                rtc_irq, retval);
 364                        goto cleanup0;
 365                }
 366        }
 367
 368        retval = rtc_register_device(mrst_rtc.rtc);
 369        if (retval)
 370                goto cleanup0;
 371
 372        dev_dbg(dev, "initialised\n");
 373        return 0;
 374
 375cleanup0:
 376        mrst_rtc.dev = NULL;
 377        dev_err(dev, "rtc-mrst: unable to initialise\n");
 378        return retval;
 379}
 380
 381static void rtc_mrst_do_shutdown(void)
 382{
 383        spin_lock_irq(&rtc_lock);
 384        mrst_irq_disable(&mrst_rtc, RTC_IRQMASK);
 385        spin_unlock_irq(&rtc_lock);
 386}
 387
 388static void rtc_mrst_do_remove(struct device *dev)
 389{
 390        struct mrst_rtc *mrst = dev_get_drvdata(dev);
 391
 392        rtc_mrst_do_shutdown();
 393
 394        mrst->rtc = NULL;
 395        mrst->dev = NULL;
 396}
 397
 398#ifdef CONFIG_PM_SLEEP
 399static int mrst_suspend(struct device *dev)
 400{
 401        struct mrst_rtc *mrst = dev_get_drvdata(dev);
 402        unsigned char   tmp;
 403
 404        /* Only the alarm might be a wakeup event source */
 405        spin_lock_irq(&rtc_lock);
 406        mrst->suspend_ctrl = tmp = vrtc_cmos_read(RTC_CONTROL);
 407        if (tmp & (RTC_PIE | RTC_AIE)) {
 408                unsigned char   mask;
 409
 410                if (device_may_wakeup(dev))
 411                        mask = RTC_IRQMASK & ~RTC_AIE;
 412                else
 413                        mask = RTC_IRQMASK;
 414                tmp &= ~mask;
 415                vrtc_cmos_write(tmp, RTC_CONTROL);
 416
 417                mrst_checkintr(mrst, tmp);
 418        }
 419        spin_unlock_irq(&rtc_lock);
 420
 421        if (tmp & RTC_AIE) {
 422                mrst->enabled_wake = 1;
 423                enable_irq_wake(mrst->irq);
 424        }
 425
 426        dev_dbg(&mrst_rtc.rtc->dev, "suspend%s, ctrl %02x\n",
 427                        (tmp & RTC_AIE) ? ", alarm may wake" : "",
 428                        tmp);
 429
 430        return 0;
 431}
 432
 433/*
 434 * We want RTC alarms to wake us from the deep power saving state
 435 */
 436static inline int mrst_poweroff(struct device *dev)
 437{
 438        return mrst_suspend(dev);
 439}
 440
 441static int mrst_resume(struct device *dev)
 442{
 443        struct mrst_rtc *mrst = dev_get_drvdata(dev);
 444        unsigned char tmp = mrst->suspend_ctrl;
 445
 446        /* Re-enable any irqs previously active */
 447        if (tmp & RTC_IRQMASK) {
 448                unsigned char   mask;
 449
 450                if (mrst->enabled_wake) {
 451                        disable_irq_wake(mrst->irq);
 452                        mrst->enabled_wake = 0;
 453                }
 454
 455                spin_lock_irq(&rtc_lock);
 456                do {
 457                        vrtc_cmos_write(tmp, RTC_CONTROL);
 458
 459                        mask = vrtc_cmos_read(RTC_INTR_FLAGS);
 460                        mask &= (tmp & RTC_IRQMASK) | RTC_IRQF;
 461                        if (!is_intr(mask))
 462                                break;
 463
 464                        rtc_update_irq(mrst->rtc, 1, mask);
 465                        tmp &= ~RTC_AIE;
 466                } while (mask & RTC_AIE);
 467                spin_unlock_irq(&rtc_lock);
 468        }
 469
 470        dev_dbg(&mrst_rtc.rtc->dev, "resume, ctrl %02x\n", tmp);
 471
 472        return 0;
 473}
 474
 475static SIMPLE_DEV_PM_OPS(mrst_pm_ops, mrst_suspend, mrst_resume);
 476#define MRST_PM_OPS (&mrst_pm_ops)
 477
 478#else
 479#define MRST_PM_OPS NULL
 480
 481static inline int mrst_poweroff(struct device *dev)
 482{
 483        return -ENOSYS;
 484}
 485
 486#endif
 487
 488static int vrtc_mrst_platform_probe(struct platform_device *pdev)
 489{
 490        return vrtc_mrst_do_probe(&pdev->dev,
 491                        platform_get_resource(pdev, IORESOURCE_MEM, 0),
 492                        platform_get_irq(pdev, 0));
 493}
 494
 495static int vrtc_mrst_platform_remove(struct platform_device *pdev)
 496{
 497        rtc_mrst_do_remove(&pdev->dev);
 498        return 0;
 499}
 500
 501static void vrtc_mrst_platform_shutdown(struct platform_device *pdev)
 502{
 503        if (system_state == SYSTEM_POWER_OFF && !mrst_poweroff(&pdev->dev))
 504                return;
 505
 506        rtc_mrst_do_shutdown();
 507}
 508
 509MODULE_ALIAS("platform:vrtc_mrst");
 510
 511static struct platform_driver vrtc_mrst_platform_driver = {
 512        .probe          = vrtc_mrst_platform_probe,
 513        .remove         = vrtc_mrst_platform_remove,
 514        .shutdown       = vrtc_mrst_platform_shutdown,
 515        .driver = {
 516                .name   = driver_name,
 517                .pm     = MRST_PM_OPS,
 518        }
 519};
 520
 521module_platform_driver(vrtc_mrst_platform_driver);
 522
 523MODULE_AUTHOR("Jacob Pan; Feng Tang");
 524MODULE_DESCRIPTION("Driver for Moorestown virtual RTC");
 525MODULE_LICENSE("GPL");
 526