linux/drivers/rtc/rtc-sirfsoc.c
<<
>>
Prefs
   1/*
   2 * SiRFSoC Real Time Clock interface for Linux
   3 *
   4 * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company.
   5 *
   6 * Licensed under GPLv2 or later.
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/err.h>
  11#include <linux/rtc.h>
  12#include <linux/platform_device.h>
  13#include <linux/slab.h>
  14#include <linux/io.h>
  15#include <linux/of.h>
  16#include <linux/rtc/sirfsoc_rtciobrg.h>
  17
  18
  19#define RTC_CN                  0x00
  20#define RTC_ALARM0              0x04
  21#define RTC_ALARM1              0x18
  22#define RTC_STATUS              0x08
  23#define RTC_SW_VALUE            0x40
  24#define SIRFSOC_RTC_AL1E        (1<<6)
  25#define SIRFSOC_RTC_AL1         (1<<4)
  26#define SIRFSOC_RTC_HZE         (1<<3)
  27#define SIRFSOC_RTC_AL0E        (1<<2)
  28#define SIRFSOC_RTC_HZ          (1<<1)
  29#define SIRFSOC_RTC_AL0         (1<<0)
  30#define RTC_DIV                 0x0c
  31#define RTC_DEEP_CTRL           0x14
  32#define RTC_CLOCK_SWITCH        0x1c
  33#define SIRFSOC_RTC_CLK         0x03    /* others are reserved */
  34
  35/* Refer to RTC DIV switch */
  36#define RTC_HZ                  16
  37
  38/* This macro is also defined in arch/arm/plat-sirfsoc/cpu.c */
  39#define RTC_SHIFT               4
  40
  41#define INTR_SYSRTC_CN          0x48
  42
  43struct sirfsoc_rtc_drv {
  44        struct rtc_device       *rtc;
  45        u32                     rtc_base;
  46        u32                     irq;
  47        /* Overflow for every 8 years extra time */
  48        u32                     overflow_rtc;
  49#ifdef CONFIG_PM
  50        u32             saved_counter;
  51        u32             saved_overflow_rtc;
  52#endif
  53};
  54
  55static int sirfsoc_rtc_read_alarm(struct device *dev,
  56                struct rtc_wkalrm *alrm)
  57{
  58        unsigned long rtc_alarm, rtc_count;
  59        struct sirfsoc_rtc_drv *rtcdrv;
  60
  61        rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
  62
  63        local_irq_disable();
  64
  65        rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
  66
  67        rtc_alarm = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_ALARM0);
  68        memset(alrm, 0, sizeof(struct rtc_wkalrm));
  69
  70        /*
  71         * assume alarm interval not beyond one round counter overflow_rtc:
  72         * 0->0xffffffff
  73         */
  74        /* if alarm is in next overflow cycle */
  75        if (rtc_count > rtc_alarm)
  76                rtc_time_to_tm((rtcdrv->overflow_rtc + 1)
  77                                << (BITS_PER_LONG - RTC_SHIFT)
  78                                | rtc_alarm >> RTC_SHIFT, &(alrm->time));
  79        else
  80                rtc_time_to_tm(rtcdrv->overflow_rtc
  81                                << (BITS_PER_LONG - RTC_SHIFT)
  82                                | rtc_alarm >> RTC_SHIFT, &(alrm->time));
  83        if (sirfsoc_rtc_iobrg_readl(
  84                        rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E)
  85                alrm->enabled = 1;
  86        local_irq_enable();
  87
  88        return 0;
  89}
  90
  91static int sirfsoc_rtc_set_alarm(struct device *dev,
  92                struct rtc_wkalrm *alrm)
  93{
  94        unsigned long rtc_status_reg, rtc_alarm;
  95        struct sirfsoc_rtc_drv *rtcdrv;
  96        rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
  97
  98        if (alrm->enabled) {
  99                rtc_tm_to_time(&(alrm->time), &rtc_alarm);
 100
 101                local_irq_disable();
 102
 103                rtc_status_reg = sirfsoc_rtc_iobrg_readl(
 104                                rtcdrv->rtc_base + RTC_STATUS);
 105                if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
 106                        /*
 107                         * An ongoing alarm in progress - ingore it and not
 108                         * to return EBUSY
 109                         */
 110                        dev_info(dev, "An old alarm was set, will be replaced by a new one\n");
 111                }
 112
 113                sirfsoc_rtc_iobrg_writel(
 114                        rtc_alarm << RTC_SHIFT, rtcdrv->rtc_base + RTC_ALARM0);
 115                rtc_status_reg &= ~0x07; /* mask out the lower status bits */
 116                /*
 117                 * This bit RTC_AL sets it as a wake-up source for Sleep Mode
 118                 * Writing 1 into this bit will clear it
 119                 */
 120                rtc_status_reg |= SIRFSOC_RTC_AL0;
 121                /* enable the RTC alarm interrupt */
 122                rtc_status_reg |= SIRFSOC_RTC_AL0E;
 123                sirfsoc_rtc_iobrg_writel(
 124                        rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
 125                local_irq_enable();
 126        } else {
 127                /*
 128                 * if this function was called with enabled=0
 129                 * then it could mean that the application is
 130                 * trying to cancel an ongoing alarm
 131                 */
 132                local_irq_disable();
 133
 134                rtc_status_reg = sirfsoc_rtc_iobrg_readl(
 135                                rtcdrv->rtc_base + RTC_STATUS);
 136                if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
 137                        /* clear the RTC status register's alarm bit */
 138                        rtc_status_reg &= ~0x07;
 139                        /* write 1 into SIRFSOC_RTC_AL0 to force a clear */
 140                        rtc_status_reg |= (SIRFSOC_RTC_AL0);
 141                        /* Clear the Alarm enable bit */
 142                        rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
 143
 144                        sirfsoc_rtc_iobrg_writel(rtc_status_reg,
 145                                        rtcdrv->rtc_base + RTC_STATUS);
 146                }
 147
 148                local_irq_enable();
 149        }
 150
 151        return 0;
 152}
 153
 154static int sirfsoc_rtc_read_time(struct device *dev,
 155                struct rtc_time *tm)
 156{
 157        unsigned long tmp_rtc = 0;
 158        struct sirfsoc_rtc_drv *rtcdrv;
 159        rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
 160        /*
 161         * This patch is taken from WinCE - Need to validate this for
 162         * correctness. To work around sirfsoc RTC counter double sync logic
 163         * fail, read several times to make sure get stable value.
 164         */
 165        do {
 166                tmp_rtc = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
 167                cpu_relax();
 168        } while (tmp_rtc != sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN));
 169
 170        rtc_time_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) |
 171                                        tmp_rtc >> RTC_SHIFT, tm);
 172        return 0;
 173}
 174
 175static int sirfsoc_rtc_set_time(struct device *dev,
 176                struct rtc_time *tm)
 177{
 178        unsigned long rtc_time;
 179        struct sirfsoc_rtc_drv *rtcdrv;
 180        rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
 181
 182        rtc_tm_to_time(tm, &rtc_time);
 183
 184        rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT);
 185
 186        sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc,
 187                        rtcdrv->rtc_base + RTC_SW_VALUE);
 188        sirfsoc_rtc_iobrg_writel(
 189                        rtc_time << RTC_SHIFT, rtcdrv->rtc_base + RTC_CN);
 190
 191        return 0;
 192}
 193
 194static int sirfsoc_rtc_ioctl(struct device *dev, unsigned int cmd,
 195                unsigned long arg)
 196{
 197        switch (cmd) {
 198        case RTC_PIE_ON:
 199        case RTC_PIE_OFF:
 200        case RTC_UIE_ON:
 201        case RTC_UIE_OFF:
 202        case RTC_AIE_ON:
 203        case RTC_AIE_OFF:
 204                return 0;
 205
 206        default:
 207                return -ENOIOCTLCMD;
 208        }
 209}
 210
 211static const struct rtc_class_ops sirfsoc_rtc_ops = {
 212        .read_time = sirfsoc_rtc_read_time,
 213        .set_time = sirfsoc_rtc_set_time,
 214        .read_alarm = sirfsoc_rtc_read_alarm,
 215        .set_alarm = sirfsoc_rtc_set_alarm,
 216        .ioctl = sirfsoc_rtc_ioctl
 217};
 218
 219static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
 220{
 221        struct sirfsoc_rtc_drv *rtcdrv = pdata;
 222        unsigned long rtc_status_reg = 0x0;
 223        unsigned long events = 0x0;
 224
 225        rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS);
 226        /* this bit will be set ONLY if an alarm was active
 227         * and it expired NOW
 228         * So this is being used as an ASSERT
 229         */
 230        if (rtc_status_reg & SIRFSOC_RTC_AL0) {
 231                /*
 232                 * clear the RTC status register's alarm bit
 233                 * mask out the lower status bits
 234                 */
 235                rtc_status_reg &= ~0x07;
 236                /* write 1 into SIRFSOC_RTC_AL0 to ACK the alarm interrupt */
 237                rtc_status_reg |= (SIRFSOC_RTC_AL0);
 238                /* Clear the Alarm enable bit */
 239                rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
 240        }
 241        sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
 242        /* this should wake up any apps polling/waiting on the read
 243         * after setting the alarm
 244         */
 245        events |= RTC_IRQF | RTC_AF;
 246        rtc_update_irq(rtcdrv->rtc, 1, events);
 247
 248        return IRQ_HANDLED;
 249}
 250
 251static const struct of_device_id sirfsoc_rtc_of_match[] = {
 252        { .compatible = "sirf,prima2-sysrtc"},
 253        {},
 254};
 255MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match);
 256
 257static int sirfsoc_rtc_probe(struct platform_device *pdev)
 258{
 259        int err;
 260        unsigned long rtc_div;
 261        struct sirfsoc_rtc_drv *rtcdrv;
 262        struct device_node *np = pdev->dev.of_node;
 263
 264        rtcdrv = devm_kzalloc(&pdev->dev,
 265                sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL);
 266        if (rtcdrv == NULL) {
 267                dev_err(&pdev->dev,
 268                        "%s: can't alloc mem for drv struct\n",
 269                        pdev->name);
 270                return -ENOMEM;
 271        }
 272
 273        err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
 274        if (err) {
 275                dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");
 276                goto error;
 277        }
 278
 279        platform_set_drvdata(pdev, rtcdrv);
 280
 281        /* Register rtc alarm as a wakeup source */
 282        device_init_wakeup(&pdev->dev, 1);
 283
 284        /*
 285         * Set SYS_RTC counter in RTC_HZ HZ Units
 286         * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
 287         * If 16HZ, therefore RTC_DIV = 1023;
 288         */
 289        rtc_div = ((32768 / RTC_HZ) / 2) - 1;
 290        sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV);
 291
 292        rtcdrv->rtc = rtc_device_register(pdev->name, &(pdev->dev),
 293                        &sirfsoc_rtc_ops, THIS_MODULE);
 294        if (IS_ERR(rtcdrv->rtc)) {
 295                err = PTR_ERR(rtcdrv->rtc);
 296                dev_err(&pdev->dev, "can't register RTC device\n");
 297                return err;
 298        }
 299
 300        /* 0x3 -> RTC_CLK */
 301        sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK,
 302                        rtcdrv->rtc_base + RTC_CLOCK_SWITCH);
 303
 304        /* reset SYS RTC ALARM0 */
 305        sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0);
 306
 307        /* reset SYS RTC ALARM1 */
 308        sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1);
 309
 310        /* Restore RTC Overflow From Register After Command Reboot */
 311        rtcdrv->overflow_rtc =
 312                sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE);
 313
 314        rtcdrv->irq = platform_get_irq(pdev, 0);
 315        err = devm_request_irq(
 316                        &pdev->dev,
 317                        rtcdrv->irq,
 318                        sirfsoc_rtc_irq_handler,
 319                        IRQF_SHARED,
 320                        pdev->name,
 321                        rtcdrv);
 322        if (err) {
 323                dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n");
 324                goto error;
 325        }
 326
 327        return 0;
 328
 329error:
 330        if (rtcdrv->rtc)
 331                rtc_device_unregister(rtcdrv->rtc);
 332
 333        return err;
 334}
 335
 336static int sirfsoc_rtc_remove(struct platform_device *pdev)
 337{
 338        struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
 339
 340        device_init_wakeup(&pdev->dev, 0);
 341        rtc_device_unregister(rtcdrv->rtc);
 342
 343        return 0;
 344}
 345
 346#ifdef CONFIG_PM
 347
 348static int sirfsoc_rtc_suspend(struct device *dev)
 349{
 350        struct platform_device *pdev = to_platform_device(dev);
 351        struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
 352        rtcdrv->overflow_rtc =
 353                sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE);
 354
 355        rtcdrv->saved_counter =
 356                sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
 357        rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc;
 358        if (device_may_wakeup(&pdev->dev))
 359                enable_irq_wake(rtcdrv->irq);
 360
 361        return 0;
 362}
 363
 364static int sirfsoc_rtc_freeze(struct device *dev)
 365{
 366        sirfsoc_rtc_suspend(dev);
 367
 368        return 0;
 369}
 370
 371static int sirfsoc_rtc_thaw(struct device *dev)
 372{
 373        u32 tmp;
 374        struct sirfsoc_rtc_drv *rtcdrv;
 375        rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
 376
 377        /*
 378         * if resume from snapshot and the rtc power is losed,
 379         * restroe the rtc settings
 380         */
 381        if (SIRFSOC_RTC_CLK != sirfsoc_rtc_iobrg_readl(
 382                        rtcdrv->rtc_base + RTC_CLOCK_SWITCH)) {
 383                u32 rtc_div;
 384                /* 0x3 -> RTC_CLK */
 385                sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK,
 386                        rtcdrv->rtc_base + RTC_CLOCK_SWITCH);
 387                /*
 388                 * Set SYS_RTC counter in RTC_HZ HZ Units
 389                 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
 390                 * If 16HZ, therefore RTC_DIV = 1023;
 391                 */
 392                rtc_div = ((32768 / RTC_HZ) / 2) - 1;
 393
 394                sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV);
 395
 396                /* reset SYS RTC ALARM0 */
 397                sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0);
 398
 399                /* reset SYS RTC ALARM1 */
 400                sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1);
 401        }
 402        rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc;
 403
 404        /*
 405         * if current counter is small than previous,
 406         * it means overflow in sleep
 407         */
 408        tmp = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
 409        if (tmp <= rtcdrv->saved_counter)
 410                rtcdrv->overflow_rtc++;
 411        /*
 412         *PWRC Value Be Changed When Suspend, Restore Overflow
 413         * In Memory To Register
 414         */
 415        sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc,
 416                        rtcdrv->rtc_base + RTC_SW_VALUE);
 417
 418        return 0;
 419}
 420
 421static int sirfsoc_rtc_resume(struct device *dev)
 422{
 423        struct platform_device *pdev = to_platform_device(dev);
 424        struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
 425        sirfsoc_rtc_thaw(dev);
 426        if (device_may_wakeup(&pdev->dev))
 427                disable_irq_wake(rtcdrv->irq);
 428
 429        return 0;
 430}
 431
 432static int sirfsoc_rtc_restore(struct device *dev)
 433{
 434        struct platform_device *pdev = to_platform_device(dev);
 435        struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
 436
 437        if (device_may_wakeup(&pdev->dev))
 438                disable_irq_wake(rtcdrv->irq);
 439        return 0;
 440}
 441
 442#else
 443#define sirfsoc_rtc_suspend     NULL
 444#define sirfsoc_rtc_resume      NULL
 445#define sirfsoc_rtc_freeze      NULL
 446#define sirfsoc_rtc_thaw        NULL
 447#define sirfsoc_rtc_restore     NULL
 448#endif
 449
 450static const struct dev_pm_ops sirfsoc_rtc_pm_ops = {
 451        .suspend = sirfsoc_rtc_suspend,
 452        .resume = sirfsoc_rtc_resume,
 453        .freeze = sirfsoc_rtc_freeze,
 454        .thaw = sirfsoc_rtc_thaw,
 455        .restore = sirfsoc_rtc_restore,
 456};
 457
 458static struct platform_driver sirfsoc_rtc_driver = {
 459        .driver = {
 460                .name = "sirfsoc-rtc",
 461                .owner = THIS_MODULE,
 462#ifdef CONFIG_PM
 463                .pm = &sirfsoc_rtc_pm_ops,
 464#endif
 465                .of_match_table = of_match_ptr(sirfsoc_rtc_of_match),
 466        },
 467        .probe = sirfsoc_rtc_probe,
 468        .remove = sirfsoc_rtc_remove,
 469};
 470module_platform_driver(sirfsoc_rtc_driver);
 471
 472MODULE_DESCRIPTION("SiRF SoC rtc driver");
 473MODULE_AUTHOR("Xianglong Du <Xianglong.Du@csr.com>");
 474MODULE_LICENSE("GPL v2");
 475MODULE_ALIAS("platform:sirfsoc-rtc");
 476
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.