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