linux/drivers/rtc/rtc-jz4740.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
   3 *  Copyright (C) 2010, Paul Cercueil <paul@crapouillou.net>
   4 *       JZ4740 SoC RTC driver
   5 *
   6 *  This program is free software; you can redistribute it and/or modify it
   7 *  under  the terms of  the GNU General Public License as published by the
   8 *  Free Software Foundation;  either version 2 of the License, or (at your
   9 *  option) any later version.
  10 *
  11 *  You should have received a copy of the GNU General Public License along
  12 *  with this program; if not, write to the Free Software Foundation, Inc.,
  13 *  675 Mass Ave, Cambridge, MA 02139, USA.
  14 *
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/platform_device.h>
  20#include <linux/rtc.h>
  21#include <linux/slab.h>
  22#include <linux/spinlock.h>
  23
  24#define JZ_REG_RTC_CTRL         0x00
  25#define JZ_REG_RTC_SEC          0x04
  26#define JZ_REG_RTC_SEC_ALARM    0x08
  27#define JZ_REG_RTC_REGULATOR    0x0C
  28#define JZ_REG_RTC_HIBERNATE    0x20
  29#define JZ_REG_RTC_SCRATCHPAD   0x34
  30
  31#define JZ_RTC_CTRL_WRDY        BIT(7)
  32#define JZ_RTC_CTRL_1HZ         BIT(6)
  33#define JZ_RTC_CTRL_1HZ_IRQ     BIT(5)
  34#define JZ_RTC_CTRL_AF          BIT(4)
  35#define JZ_RTC_CTRL_AF_IRQ      BIT(3)
  36#define JZ_RTC_CTRL_AE          BIT(2)
  37#define JZ_RTC_CTRL_ENABLE      BIT(0)
  38
  39struct jz4740_rtc {
  40        struct resource *mem;
  41        void __iomem *base;
  42
  43        struct rtc_device *rtc;
  44
  45        unsigned int irq;
  46
  47        spinlock_t lock;
  48};
  49
  50static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg)
  51{
  52        return readl(rtc->base + reg);
  53}
  54
  55static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
  56{
  57        uint32_t ctrl;
  58        int timeout = 1000;
  59
  60        do {
  61                ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
  62        } while (!(ctrl & JZ_RTC_CTRL_WRDY) && --timeout);
  63
  64        return timeout ? 0 : -EIO;
  65}
  66
  67static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
  68        uint32_t val)
  69{
  70        int ret;
  71        ret = jz4740_rtc_wait_write_ready(rtc);
  72        if (ret == 0)
  73                writel(val, rtc->base + reg);
  74
  75        return ret;
  76}
  77
  78static int jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask,
  79        bool set)
  80{
  81        int ret;
  82        unsigned long flags;
  83        uint32_t ctrl;
  84
  85        spin_lock_irqsave(&rtc->lock, flags);
  86
  87        ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
  88
  89        /* Don't clear interrupt flags by accident */
  90        ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF;
  91
  92        if (set)
  93                ctrl |= mask;
  94        else
  95                ctrl &= ~mask;
  96
  97        ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl);
  98
  99        spin_unlock_irqrestore(&rtc->lock, flags);
 100
 101        return ret;
 102}
 103
 104static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
 105{
 106        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 107        uint32_t secs, secs2;
 108        int timeout = 5;
 109
 110        /* If the seconds register is read while it is updated, it can contain a
 111         * bogus value. This can be avoided by making sure that two consecutive
 112         * reads have the same value.
 113         */
 114        secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
 115        secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
 116
 117        while (secs != secs2 && --timeout) {
 118                secs = secs2;
 119                secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
 120        }
 121
 122        if (timeout == 0)
 123                return -EIO;
 124
 125        rtc_time_to_tm(secs, time);
 126
 127        return rtc_valid_tm(time);
 128}
 129
 130static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs)
 131{
 132        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 133
 134        return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs);
 135}
 136
 137static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 138{
 139        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 140        uint32_t secs;
 141        uint32_t ctrl;
 142
 143        secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
 144
 145        ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
 146
 147        alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE);
 148        alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF);
 149
 150        rtc_time_to_tm(secs, &alrm->time);
 151
 152        return rtc_valid_tm(&alrm->time);
 153}
 154
 155static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 156{
 157        int ret;
 158        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 159        unsigned long secs;
 160
 161        rtc_tm_to_time(&alrm->time, &secs);
 162
 163        ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs);
 164        if (!ret)
 165                ret = jz4740_rtc_ctrl_set_bits(rtc,
 166                        JZ_RTC_CTRL_AE | JZ_RTC_CTRL_AF_IRQ, alrm->enabled);
 167
 168        return ret;
 169}
 170
 171static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
 172{
 173        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 174        return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, enable);
 175}
 176
 177static struct rtc_class_ops jz4740_rtc_ops = {
 178        .read_time      = jz4740_rtc_read_time,
 179        .set_mmss       = jz4740_rtc_set_mmss,
 180        .read_alarm     = jz4740_rtc_read_alarm,
 181        .set_alarm      = jz4740_rtc_set_alarm,
 182        .alarm_irq_enable = jz4740_rtc_alarm_irq_enable,
 183};
 184
 185static irqreturn_t jz4740_rtc_irq(int irq, void *data)
 186{
 187        struct jz4740_rtc *rtc = data;
 188        uint32_t ctrl;
 189        unsigned long events = 0;
 190
 191        ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
 192
 193        if (ctrl & JZ_RTC_CTRL_1HZ)
 194                events |= (RTC_UF | RTC_IRQF);
 195
 196        if (ctrl & JZ_RTC_CTRL_AF)
 197                events |= (RTC_AF | RTC_IRQF);
 198
 199        rtc_update_irq(rtc->rtc, 1, events);
 200
 201        jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, false);
 202
 203        return IRQ_HANDLED;
 204}
 205
 206void jz4740_rtc_poweroff(struct device *dev)
 207{
 208        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 209        jz4740_rtc_reg_write(rtc, JZ_REG_RTC_HIBERNATE, 1);
 210}
 211EXPORT_SYMBOL_GPL(jz4740_rtc_poweroff);
 212
 213static int __devinit jz4740_rtc_probe(struct platform_device *pdev)
 214{
 215        int ret;
 216        struct jz4740_rtc *rtc;
 217        uint32_t scratchpad;
 218
 219        rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
 220        if (!rtc)
 221                return -ENOMEM;
 222
 223        rtc->irq = platform_get_irq(pdev, 0);
 224        if (rtc->irq < 0) {
 225                ret = -ENOENT;
 226                dev_err(&pdev->dev, "Failed to get platform irq\n");
 227                goto err_free;
 228        }
 229
 230        rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 231        if (!rtc->mem) {
 232                ret = -ENOENT;
 233                dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
 234                goto err_free;
 235        }
 236
 237        rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem),
 238                                        pdev->name);
 239        if (!rtc->mem) {
 240                ret = -EBUSY;
 241                dev_err(&pdev->dev, "Failed to request mmio memory region\n");
 242                goto err_free;
 243        }
 244
 245        rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem));
 246        if (!rtc->base) {
 247                ret = -EBUSY;
 248                dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
 249                goto err_release_mem_region;
 250        }
 251
 252        spin_lock_init(&rtc->lock);
 253
 254        platform_set_drvdata(pdev, rtc);
 255
 256        device_init_wakeup(&pdev->dev, 1);
 257
 258        rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops,
 259                                        THIS_MODULE);
 260        if (IS_ERR(rtc->rtc)) {
 261                ret = PTR_ERR(rtc->rtc);
 262                dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret);
 263                goto err_iounmap;
 264        }
 265
 266        ret = request_irq(rtc->irq, jz4740_rtc_irq, 0,
 267                                pdev->name, rtc);
 268        if (ret) {
 269                dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret);
 270                goto err_unregister_rtc;
 271        }
 272
 273        scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD);
 274        if (scratchpad != 0x12345678) {
 275                ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678);
 276                ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
 277                if (ret) {
 278                        dev_err(&pdev->dev, "Could not write write to RTC registers\n");
 279                        goto err_free_irq;
 280                }
 281        }
 282
 283        return 0;
 284
 285err_free_irq:
 286        free_irq(rtc->irq, rtc);
 287err_unregister_rtc:
 288        rtc_device_unregister(rtc->rtc);
 289err_iounmap:
 290        platform_set_drvdata(pdev, NULL);
 291        iounmap(rtc->base);
 292err_release_mem_region:
 293        release_mem_region(rtc->mem->start, resource_size(rtc->mem));
 294err_free:
 295        kfree(rtc);
 296
 297        return ret;
 298}
 299
 300static int __devexit jz4740_rtc_remove(struct platform_device *pdev)
 301{
 302        struct jz4740_rtc *rtc = platform_get_drvdata(pdev);
 303
 304        free_irq(rtc->irq, rtc);
 305
 306        rtc_device_unregister(rtc->rtc);
 307
 308        iounmap(rtc->base);
 309        release_mem_region(rtc->mem->start, resource_size(rtc->mem));
 310
 311        kfree(rtc);
 312
 313        platform_set_drvdata(pdev, NULL);
 314
 315        return 0;
 316}
 317
 318
 319#ifdef CONFIG_PM
 320static int jz4740_rtc_suspend(struct device *dev)
 321{
 322        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 323
 324        if (device_may_wakeup(dev))
 325                enable_irq_wake(rtc->irq);
 326        return 0;
 327}
 328
 329static int jz4740_rtc_resume(struct device *dev)
 330{
 331        struct jz4740_rtc *rtc = dev_get_drvdata(dev);
 332
 333        if (device_may_wakeup(dev))
 334                disable_irq_wake(rtc->irq);
 335        return 0;
 336}
 337
 338static const struct dev_pm_ops jz4740_pm_ops = {
 339        .suspend = jz4740_rtc_suspend,
 340        .resume  = jz4740_rtc_resume,
 341};
 342#define JZ4740_RTC_PM_OPS (&jz4740_pm_ops)
 343
 344#else
 345#define JZ4740_RTC_PM_OPS NULL
 346#endif  /* CONFIG_PM */
 347
 348static struct platform_driver jz4740_rtc_driver = {
 349        .probe   = jz4740_rtc_probe,
 350        .remove  = __devexit_p(jz4740_rtc_remove),
 351        .driver  = {
 352                .name  = "jz4740-rtc",
 353                .owner = THIS_MODULE,
 354                .pm    = JZ4740_RTC_PM_OPS,
 355        },
 356};
 357
 358module_platform_driver(jz4740_rtc_driver);
 359
 360MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 361MODULE_LICENSE("GPL");
 362MODULE_DESCRIPTION("RTC driver for the JZ4740 SoC\n");
 363MODULE_ALIAS("platform:jz4740-rtc");
 364
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.