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