linux/drivers/rtc/rtc-bfin.c
<<
>>
Prefs
   1/*
   2 * Blackfin On-Chip Real Time Clock Driver
   3 *  Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789]
   4 *
   5 * Copyright 2004-2008 Analog Devices Inc.
   6 *
   7 * Enter bugs at http://blackfin.uclinux.org/
   8 *
   9 * Licensed under the GPL-2 or later.
  10 */
  11
  12/* The biggest issue we deal with in this driver is that register writes are
  13 * synced to the RTC frequency of 1Hz.  So if you write to a register and
  14 * attempt to write again before the first write has completed, the new write
  15 * is simply discarded.  This can easily be troublesome if userspace disables
  16 * one event (say periodic) and then right after enables an event (say alarm).
  17 * Since all events are maintained in the same interrupt mask register, if
  18 * we wrote to it to disable the first event and then wrote to it again to
  19 * enable the second event, that second event would not be enabled as the
  20 * write would be discarded and things quickly fall apart.
  21 *
  22 * To keep this delay from significantly degrading performance (we, in theory,
  23 * would have to sleep for up to 1 second everytime we wanted to write a
  24 * register), we only check the write pending status before we start to issue
  25 * a new write.  We bank on the idea that it doesnt matter when the sync
  26 * happens so long as we don't attempt another write before it does.  The only
  27 * time userspace would take this penalty is when they try and do multiple
  28 * operations right after another ... but in this case, they need to take the
  29 * sync penalty, so we should be OK.
  30 *
  31 * Also note that the RTC_ISTAT register does not suffer this penalty; its
  32 * writes to clear status registers complete immediately.
  33 */
  34
  35/* It may seem odd that there is no SWCNT code in here (which would be exposed
  36 * via the periodic interrupt event, or PIE).  Since the Blackfin RTC peripheral
  37 * runs in units of seconds (N/HZ) but the Linux framework runs in units of HZ
  38 * (2^N HZ), there is no point in keeping code that only provides 1 HZ PIEs.
  39 * The same exact behavior can be accomplished by using the update interrupt
  40 * event (UIE).  Maybe down the line the RTC peripheral will suck less in which
  41 * case we can re-introduce PIE support.
  42 */
  43
  44#include <linux/bcd.h>
  45#include <linux/completion.h>
  46#include <linux/delay.h>
  47#include <linux/init.h>
  48#include <linux/interrupt.h>
  49#include <linux/kernel.h>
  50#include <linux/module.h>
  51#include <linux/platform_device.h>
  52#include <linux/rtc.h>
  53#include <linux/seq_file.h>
  54
  55#include <asm/blackfin.h>
  56
  57#define dev_dbg_stamp(dev) dev_dbg(dev, "%s:%i: here i am\n", __func__, __LINE__)
  58
  59struct bfin_rtc {
  60        struct rtc_device *rtc_dev;
  61        struct rtc_time rtc_alarm;
  62        u16 rtc_wrote_regs;
  63};
  64
  65/* Bit values for the ISTAT / ICTL registers */
  66#define RTC_ISTAT_WRITE_COMPLETE  0x8000
  67#define RTC_ISTAT_WRITE_PENDING   0x4000
  68#define RTC_ISTAT_ALARM_DAY       0x0040
  69#define RTC_ISTAT_24HR            0x0020
  70#define RTC_ISTAT_HOUR            0x0010
  71#define RTC_ISTAT_MIN             0x0008
  72#define RTC_ISTAT_SEC             0x0004
  73#define RTC_ISTAT_ALARM           0x0002
  74#define RTC_ISTAT_STOPWATCH       0x0001
  75
  76/* Shift values for RTC_STAT register */
  77#define DAY_BITS_OFF    17
  78#define HOUR_BITS_OFF   12
  79#define MIN_BITS_OFF    6
  80#define SEC_BITS_OFF    0
  81
  82/* Some helper functions to convert between the common RTC notion of time
  83 * and the internal Blackfin notion that is encoded in 32bits.
  84 */
  85static inline u32 rtc_time_to_bfin(unsigned long now)
  86{
  87        u32 sec  = (now % 60);
  88        u32 min  = (now % (60 * 60)) / 60;
  89        u32 hour = (now % (60 * 60 * 24)) / (60 * 60);
  90        u32 days = (now / (60 * 60 * 24));
  91        return (sec  << SEC_BITS_OFF) +
  92               (min  << MIN_BITS_OFF) +
  93               (hour << HOUR_BITS_OFF) +
  94               (days << DAY_BITS_OFF);
  95}
  96static inline unsigned long rtc_bfin_to_time(u32 rtc_bfin)
  97{
  98        return (((rtc_bfin >> SEC_BITS_OFF)  & 0x003F)) +
  99               (((rtc_bfin >> MIN_BITS_OFF)  & 0x003F) * 60) +
 100               (((rtc_bfin >> HOUR_BITS_OFF) & 0x001F) * 60 * 60) +
 101               (((rtc_bfin >> DAY_BITS_OFF)  & 0x7FFF) * 60 * 60 * 24);
 102}
 103static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm)
 104{
 105        rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm);
 106}
 107
 108/**
 109 *      bfin_rtc_sync_pending - make sure pending writes have complete
 110 *
 111 * Wait for the previous write to a RTC register to complete.
 112 * Unfortunately, we can't sleep here as that introduces a race condition when
 113 * turning on interrupt events.  Consider this:
 114 *  - process sets alarm
 115 *  - process enables alarm
 116 *  - process sleeps while waiting for rtc write to sync
 117 *  - interrupt fires while process is sleeping
 118 *  - interrupt acks the event by writing to ISTAT
 119 *  - interrupt sets the WRITE PENDING bit
 120 *  - interrupt handler finishes
 121 *  - process wakes up, sees WRITE PENDING bit set, goes to sleep
 122 *  - interrupt fires while process is sleeping
 123 * If anyone can point out the obvious solution here, i'm listening :).  This
 124 * shouldn't be an issue on an SMP or preempt system as this function should
 125 * only be called with the rtc lock held.
 126 *
 127 * Other options:
 128 *  - disable PREN so the sync happens at 32.768kHZ ... but this changes the
 129 *    inc rate for all RTC registers from 1HZ to 32.768kHZ ...
 130 *  - use the write complete IRQ
 131 */
 132/*
 133static void bfin_rtc_sync_pending_polled(void)
 134{
 135        while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE))
 136                if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING))
 137                        break;
 138        bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE);
 139}
 140*/
 141static DECLARE_COMPLETION(bfin_write_complete);
 142static void bfin_rtc_sync_pending(struct device *dev)
 143{
 144        dev_dbg_stamp(dev);
 145        while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)
 146                wait_for_completion_timeout(&bfin_write_complete, HZ * 5);
 147        dev_dbg_stamp(dev);
 148}
 149
 150/**
 151 *      bfin_rtc_reset - set RTC to sane/known state
 152 *
 153 * Initialize the RTC.  Enable pre-scaler to scale RTC clock
 154 * to 1Hz and clear interrupt/status registers.
 155 */
 156static void bfin_rtc_reset(struct device *dev, u16 rtc_ictl)
 157{
 158        struct bfin_rtc *rtc = dev_get_drvdata(dev);
 159        dev_dbg_stamp(dev);
 160        bfin_rtc_sync_pending(dev);
 161        bfin_write_RTC_PREN(0x1);
 162        bfin_write_RTC_ICTL(rtc_ictl);
 163        bfin_write_RTC_ALARM(0);
 164        bfin_write_RTC_ISTAT(0xFFFF);
 165        rtc->rtc_wrote_regs = 0;
 166}
 167
 168/**
 169 *      bfin_rtc_interrupt - handle interrupt from RTC
 170 *
 171 * Since we handle all RTC events here, we have to make sure the requested
 172 * interrupt is enabled (in RTC_ICTL) as the event status register (RTC_ISTAT)
 173 * always gets updated regardless of the interrupt being enabled.  So when one
 174 * even we care about (e.g. stopwatch) goes off, we don't want to turn around
 175 * and say that other events have happened as well (e.g. second).  We do not
 176 * have to worry about pending writes to the RTC_ICTL register as interrupts
 177 * only fire if they are enabled in the RTC_ICTL register.
 178 */
 179static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id)
 180{
 181        struct device *dev = dev_id;
 182        struct bfin_rtc *rtc = dev_get_drvdata(dev);
 183        unsigned long events = 0;
 184        bool write_complete = false;
 185        u16 rtc_istat, rtc_ictl;
 186
 187        dev_dbg_stamp(dev);
 188
 189        rtc_istat = bfin_read_RTC_ISTAT();
 190        rtc_ictl = bfin_read_RTC_ICTL();
 191
 192        if (rtc_istat & RTC_ISTAT_WRITE_COMPLETE) {
 193                bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE);
 194                write_complete = true;
 195                complete(&bfin_write_complete);
 196        }
 197
 198        if (rtc_ictl & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) {
 199                if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) {
 200                        bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY);
 201                        events |= RTC_AF | RTC_IRQF;
 202                }
 203        }
 204
 205        if (rtc_ictl & RTC_ISTAT_SEC) {
 206                if (rtc_istat & RTC_ISTAT_SEC) {
 207                        bfin_write_RTC_ISTAT(RTC_ISTAT_SEC);
 208                        events |= RTC_UF | RTC_IRQF;
 209                }
 210        }
 211
 212        if (events)
 213                rtc_update_irq(rtc->rtc_dev, 1, events);
 214
 215        if (write_complete || events)
 216                return IRQ_HANDLED;
 217        else
 218                return IRQ_NONE;
 219}
 220
 221static void bfin_rtc_int_set(u16 rtc_int)
 222{
 223        bfin_write_RTC_ISTAT(rtc_int);
 224        bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | rtc_int);
 225}
 226static void bfin_rtc_int_clear(u16 rtc_int)
 227{
 228        bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & rtc_int);
 229}
 230static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc)
 231{
 232        /* Blackfin has different bits for whether the alarm is
 233         * more than 24 hours away.
 234         */
 235        bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY);
 236}
 237static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 238{
 239        struct bfin_rtc *rtc = dev_get_drvdata(dev);
 240        int ret = 0;
 241
 242        dev_dbg_stamp(dev);
 243
 244        bfin_rtc_sync_pending(dev);
 245
 246        switch (cmd) {
 247        case RTC_UIE_ON:
 248                dev_dbg_stamp(dev);
 249                bfin_rtc_int_set(RTC_ISTAT_SEC);
 250                break;
 251        case RTC_UIE_OFF:
 252                dev_dbg_stamp(dev);
 253                bfin_rtc_int_clear(~RTC_ISTAT_SEC);
 254                break;
 255
 256        case RTC_AIE_ON:
 257                dev_dbg_stamp(dev);
 258                bfin_rtc_int_set_alarm(rtc);
 259                break;
 260        case RTC_AIE_OFF:
 261                dev_dbg_stamp(dev);
 262                bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
 263                break;
 264
 265        default:
 266                dev_dbg_stamp(dev);
 267                ret = -ENOIOCTLCMD;
 268        }
 269
 270        return ret;
 271}
 272
 273static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm)
 274{
 275        struct bfin_rtc *rtc = dev_get_drvdata(dev);
 276
 277        dev_dbg_stamp(dev);
 278
 279        if (rtc->rtc_wrote_regs & 0x1)
 280                bfin_rtc_sync_pending(dev);
 281
 282        rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm);
 283
 284        return 0;
 285}
 286
 287static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm)
 288{
 289        struct bfin_rtc *rtc = dev_get_drvdata(dev);
 290        int ret;
 291        unsigned long now;
 292
 293        dev_dbg_stamp(dev);
 294
 295        ret = rtc_tm_to_time(tm, &now);
 296        if (ret == 0) {
 297                if (rtc->rtc_wrote_regs & 0x1)
 298                        bfin_rtc_sync_pending(dev);
 299                bfin_write_RTC_STAT(rtc_time_to_bfin(now));
 300                rtc->rtc_wrote_regs = 0x1;
 301        }
 302
 303        return ret;
 304}
 305
 306static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 307{
 308        struct bfin_rtc *rtc = dev_get_drvdata(dev);
 309        dev_dbg_stamp(dev);
 310        alrm->time = rtc->rtc_alarm;
 311        bfin_rtc_sync_pending(dev);
 312        alrm->enabled = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
 313        return 0;
 314}
 315
 316static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 317{
 318        struct bfin_rtc *rtc = dev_get_drvdata(dev);
 319        unsigned long rtc_alarm;
 320
 321        dev_dbg_stamp(dev);
 322
 323        if (rtc_tm_to_time(&alrm->time, &rtc_alarm))
 324                return -EINVAL;
 325
 326        rtc->rtc_alarm = alrm->time;
 327
 328        bfin_rtc_sync_pending(dev);
 329        bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm));
 330        if (alrm->enabled)
 331                bfin_rtc_int_set_alarm(rtc);
 332
 333        return 0;
 334}
 335
 336static int bfin_rtc_proc(struct device *dev, struct seq_file *seq)
 337{
 338#define yesno(x) ((x) ? "yes" : "no")
 339        u16 ictl = bfin_read_RTC_ICTL();
 340        dev_dbg_stamp(dev);
 341        seq_printf(seq,
 342                "alarm_IRQ\t: %s\n"
 343                "wkalarm_IRQ\t: %s\n"
 344                "seconds_IRQ\t: %s\n",
 345                yesno(ictl & RTC_ISTAT_ALARM),
 346                yesno(ictl & RTC_ISTAT_ALARM_DAY),
 347                yesno(ictl & RTC_ISTAT_SEC));
 348        return 0;
 349#undef yesno
 350}
 351
 352static struct rtc_class_ops bfin_rtc_ops = {
 353        .ioctl         = bfin_rtc_ioctl,
 354        .read_time     = bfin_rtc_read_time,
 355        .set_time      = bfin_rtc_set_time,
 356        .read_alarm    = bfin_rtc_read_alarm,
 357        .set_alarm     = bfin_rtc_set_alarm,
 358        .proc          = bfin_rtc_proc,
 359};
 360
 361static int __devinit bfin_rtc_probe(struct platform_device *pdev)
 362{
 363        struct bfin_rtc *rtc;
 364        struct device *dev = &pdev->dev;
 365        int ret = 0;
 366        unsigned long timeout;
 367
 368        dev_dbg_stamp(dev);
 369
 370        /* Allocate memory for our RTC struct */
 371        rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
 372        if (unlikely(!rtc))
 373                return -ENOMEM;
 374        platform_set_drvdata(pdev, rtc);
 375        device_init_wakeup(dev, 1);
 376
 377        /* Grab the IRQ and init the hardware */
 378        ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev);
 379        if (unlikely(ret))
 380                goto err;
 381        /* sometimes the bootloader touched things, but the write complete was not
 382         * enabled, so let's just do a quick timeout here since the IRQ will not fire ...
 383         */
 384        timeout = jiffies + HZ;
 385        while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)
 386                if (time_after(jiffies, timeout))
 387                        break;
 388        bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE);
 389        bfin_write_RTC_SWCNT(0);
 390
 391        /* Register our RTC with the RTC framework */
 392        rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE);
 393        if (unlikely(IS_ERR(rtc->rtc_dev))) {
 394                ret = PTR_ERR(rtc->rtc_dev);
 395                goto err_irq;
 396        }
 397
 398        return 0;
 399
 400 err_irq:
 401        free_irq(IRQ_RTC, dev);
 402 err:
 403        kfree(rtc);
 404        return ret;
 405}
 406
 407static int __devexit bfin_rtc_remove(struct platform_device *pdev)
 408{
 409        struct bfin_rtc *rtc = platform_get_drvdata(pdev);
 410        struct device *dev = &pdev->dev;
 411
 412        bfin_rtc_reset(dev, 0);
 413        free_irq(IRQ_RTC, dev);
 414        rtc_device_unregister(rtc->rtc_dev);
 415        platform_set_drvdata(pdev, NULL);
 416        kfree(rtc);
 417
 418        return 0;
 419}
 420
 421#ifdef CONFIG_PM
 422static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 423{
 424        if (device_may_wakeup(&pdev->dev)) {
 425                enable_irq_wake(IRQ_RTC);
 426                bfin_rtc_sync_pending(&pdev->dev);
 427        } else
 428                bfin_rtc_int_clear(-1);
 429
 430        return 0;
 431}
 432
 433static int bfin_rtc_resume(struct platform_device *pdev)
 434{
 435        if (device_may_wakeup(&pdev->dev))
 436                disable_irq_wake(IRQ_RTC);
 437        else
 438                bfin_write_RTC_ISTAT(-1);
 439
 440        return 0;
 441}
 442#else
 443# define bfin_rtc_suspend NULL
 444# define bfin_rtc_resume  NULL
 445#endif
 446
 447static struct platform_driver bfin_rtc_driver = {
 448        .driver         = {
 449                .name   = "rtc-bfin",
 450                .owner  = THIS_MODULE,
 451        },
 452        .probe          = bfin_rtc_probe,
 453        .remove         = __devexit_p(bfin_rtc_remove),
 454        .suspend        = bfin_rtc_suspend,
 455        .resume         = bfin_rtc_resume,
 456};
 457
 458static int __init bfin_rtc_init(void)
 459{
 460        return platform_driver_register(&bfin_rtc_driver);
 461}
 462
 463static void __exit bfin_rtc_exit(void)
 464{
 465        platform_driver_unregister(&bfin_rtc_driver);
 466}
 467
 468module_init(bfin_rtc_init);
 469module_exit(bfin_rtc_exit);
 470
 471MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver");
 472MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
 473MODULE_LICENSE("GPL");
 474MODULE_ALIAS("platform:rtc-bfin");
 475