linux/drivers/rtc/rtc-stmp3xxx.c
<<
>>
Prefs
   1/*
   2 * Freescale STMP37XX/STMP378X Real Time Clock driver
   3 *
   4 * Copyright (c) 2007 Sigmatel, Inc.
   5 * Peter Hartley, <peter.hartley@sigmatel.com>
   6 *
   7 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
   8 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
   9 * Copyright 2011 Wolfram Sang, Pengutronix e.K.
  10 */
  11
  12/*
  13 * The code contained herein is licensed under the GNU General Public
  14 * License. You may obtain a copy of the GNU General Public License
  15 * Version 2 or later at the following locations:
  16 *
  17 * http://www.opensource.org/licenses/gpl-license.html
  18 * http://www.gnu.org/copyleft/gpl.html
  19 */
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/io.h>
  23#include <linux/init.h>
  24#include <linux/platform_device.h>
  25#include <linux/interrupt.h>
  26#include <linux/rtc.h>
  27#include <linux/slab.h>
  28#include <linux/of_device.h>
  29#include <linux/of.h>
  30#include <linux/stmp_device.h>
  31#include <linux/stmp3xxx_rtc_wdt.h>
  32
  33#define STMP3XXX_RTC_CTRL                       0x0
  34#define STMP3XXX_RTC_CTRL_SET                   0x4
  35#define STMP3XXX_RTC_CTRL_CLR                   0x8
  36#define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN          0x00000001
  37#define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN        0x00000002
  38#define STMP3XXX_RTC_CTRL_ALARM_IRQ             0x00000004
  39#define STMP3XXX_RTC_CTRL_WATCHDOGEN            0x00000010
  40
  41#define STMP3XXX_RTC_STAT                       0x10
  42#define STMP3XXX_RTC_STAT_STALE_SHIFT           16
  43#define STMP3XXX_RTC_STAT_RTC_PRESENT           0x80000000
  44
  45#define STMP3XXX_RTC_SECONDS                    0x30
  46
  47#define STMP3XXX_RTC_ALARM                      0x40
  48
  49#define STMP3XXX_RTC_WATCHDOG                   0x50
  50
  51#define STMP3XXX_RTC_PERSISTENT0                0x60
  52#define STMP3XXX_RTC_PERSISTENT0_SET            0x64
  53#define STMP3XXX_RTC_PERSISTENT0_CLR            0x68
  54#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN  0x00000002
  55#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN       0x00000004
  56#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE     0x00000080
  57
  58#define STMP3XXX_RTC_PERSISTENT1                0x70
  59/* missing bitmask in headers */
  60#define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER  0x80000000
  61
  62struct stmp3xxx_rtc_data {
  63        struct rtc_device *rtc;
  64        void __iomem *io;
  65        int irq_alarm;
  66};
  67
  68#if IS_ENABLED(CONFIG_STMP3XXX_RTC_WATCHDOG)
  69/**
  70 * stmp3xxx_wdt_set_timeout - configure the watchdog inside the STMP3xxx RTC
  71 * @dev: the parent device of the watchdog (= the RTC)
  72 * @timeout: the desired value for the timeout register of the watchdog.
  73 *           0 disables the watchdog
  74 *
  75 * The watchdog needs one register and two bits which are in the RTC domain.
  76 * To handle the resource conflict, the RTC driver will create another
  77 * platform_device for the watchdog driver as a child of the RTC device.
  78 * The watchdog driver is passed the below accessor function via platform_data
  79 * to configure the watchdog. Locking is not needed because accessing SET/CLR
  80 * registers is atomic.
  81 */
  82
  83static void stmp3xxx_wdt_set_timeout(struct device *dev, u32 timeout)
  84{
  85        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
  86
  87        if (timeout) {
  88                writel(timeout, rtc_data->io + STMP3XXX_RTC_WATCHDOG);
  89                writel(STMP3XXX_RTC_CTRL_WATCHDOGEN,
  90                       rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_SET);
  91                writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER,
  92                       rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_SET);
  93        } else {
  94                writel(STMP3XXX_RTC_CTRL_WATCHDOGEN,
  95                       rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR);
  96                writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER,
  97                       rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_CLR);
  98        }
  99}
 100
 101static struct stmp3xxx_wdt_pdata wdt_pdata = {
 102        .wdt_set_timeout = stmp3xxx_wdt_set_timeout,
 103};
 104
 105static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)
 106{
 107        struct platform_device *wdt_pdev =
 108                platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id);
 109
 110        if (wdt_pdev) {
 111                wdt_pdev->dev.parent = &rtc_pdev->dev;
 112                wdt_pdev->dev.platform_data = &wdt_pdata;
 113                platform_device_add(wdt_pdev);
 114        }
 115}
 116#else
 117static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)
 118{
 119}
 120#endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */
 121
 122static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data)
 123{
 124        /*
 125         * The datasheet doesn't say which way round the
 126         * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0,
 127         * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS
 128         */
 129        while (readl(rtc_data->io + STMP3XXX_RTC_STAT) &
 130                        (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT))
 131                cpu_relax();
 132}
 133
 134/* Time read/write */
 135static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 136{
 137        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 138
 139        stmp3xxx_wait_time(rtc_data);
 140        rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm);
 141        return 0;
 142}
 143
 144static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t)
 145{
 146        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 147
 148        writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS);
 149        stmp3xxx_wait_time(rtc_data);
 150        return 0;
 151}
 152
 153/* interrupt(s) handler */
 154static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id)
 155{
 156        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id);
 157        u32 status = readl(rtc_data->io + STMP3XXX_RTC_CTRL);
 158
 159        if (status & STMP3XXX_RTC_CTRL_ALARM_IRQ) {
 160                writel(STMP3XXX_RTC_CTRL_ALARM_IRQ,
 161                                rtc_data->io + STMP3XXX_RTC_CTRL_CLR);
 162                rtc_update_irq(rtc_data->rtc, 1, RTC_AF | RTC_IRQF);
 163                return IRQ_HANDLED;
 164        }
 165
 166        return IRQ_NONE;
 167}
 168
 169static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled)
 170{
 171        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 172
 173        if (enabled) {
 174                writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
 175                                STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN,
 176                                rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET);
 177                writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN,
 178                                rtc_data->io + STMP3XXX_RTC_CTRL_SET);
 179        } else {
 180                writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
 181                                STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN,
 182                                rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR);
 183                writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN,
 184                                rtc_data->io + STMP3XXX_RTC_CTRL_CLR);
 185        }
 186        return 0;
 187}
 188
 189static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 190{
 191        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 192
 193        rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time);
 194        return 0;
 195}
 196
 197static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 198{
 199        unsigned long t;
 200        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 201
 202        rtc_tm_to_time(&alm->time, &t);
 203        writel(t, rtc_data->io + STMP3XXX_RTC_ALARM);
 204
 205        stmp3xxx_alarm_irq_enable(dev, alm->enabled);
 206
 207        return 0;
 208}
 209
 210static struct rtc_class_ops stmp3xxx_rtc_ops = {
 211        .alarm_irq_enable =
 212                          stmp3xxx_alarm_irq_enable,
 213        .read_time      = stmp3xxx_rtc_gettime,
 214        .set_mmss       = stmp3xxx_rtc_set_mmss,
 215        .read_alarm     = stmp3xxx_rtc_read_alarm,
 216        .set_alarm      = stmp3xxx_rtc_set_alarm,
 217};
 218
 219static int stmp3xxx_rtc_remove(struct platform_device *pdev)
 220{
 221        struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(pdev);
 222
 223        if (!rtc_data)
 224                return 0;
 225
 226        writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN,
 227                        rtc_data->io + STMP3XXX_RTC_CTRL_CLR);
 228        platform_set_drvdata(pdev, NULL);
 229
 230        return 0;
 231}
 232
 233static int stmp3xxx_rtc_probe(struct platform_device *pdev)
 234{
 235        struct stmp3xxx_rtc_data *rtc_data;
 236        struct resource *r;
 237        int err;
 238
 239        rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL);
 240        if (!rtc_data)
 241                return -ENOMEM;
 242
 243        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 244        if (!r) {
 245                dev_err(&pdev->dev, "failed to get resource\n");
 246                return -ENXIO;
 247        }
 248
 249        rtc_data->io = devm_ioremap(&pdev->dev, r->start, resource_size(r));
 250        if (!rtc_data->io) {
 251                dev_err(&pdev->dev, "ioremap failed\n");
 252                return -EIO;
 253        }
 254
 255        rtc_data->irq_alarm = platform_get_irq(pdev, 0);
 256
 257        if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) &
 258                        STMP3XXX_RTC_STAT_RTC_PRESENT)) {
 259                dev_err(&pdev->dev, "no device onboard\n");
 260                return -ENODEV;
 261        }
 262
 263        platform_set_drvdata(pdev, rtc_data);
 264
 265        stmp_reset_block(rtc_data->io);
 266        writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
 267                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
 268                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
 269                        rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR);
 270
 271        writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN |
 272                        STMP3XXX_RTC_CTRL_ALARM_IRQ_EN,
 273                        rtc_data->io + STMP3XXX_RTC_CTRL_CLR);
 274
 275        rtc_data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 276                                &stmp3xxx_rtc_ops, THIS_MODULE);
 277        if (IS_ERR(rtc_data->rtc)) {
 278                err = PTR_ERR(rtc_data->rtc);
 279                goto out;
 280        }
 281
 282        err = devm_request_irq(&pdev->dev, rtc_data->irq_alarm,
 283                        stmp3xxx_rtc_interrupt, 0, "RTC alarm", &pdev->dev);
 284        if (err) {
 285                dev_err(&pdev->dev, "Cannot claim IRQ%d\n",
 286                        rtc_data->irq_alarm);
 287                goto out;
 288        }
 289
 290        stmp3xxx_wdt_register(pdev);
 291        return 0;
 292
 293out:
 294        platform_set_drvdata(pdev, NULL);
 295        return err;
 296}
 297
 298#ifdef CONFIG_PM_SLEEP
 299static int stmp3xxx_rtc_suspend(struct device *dev)
 300{
 301        return 0;
 302}
 303
 304static int stmp3xxx_rtc_resume(struct device *dev)
 305{
 306        struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 307
 308        stmp_reset_block(rtc_data->io);
 309        writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
 310                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
 311                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
 312                        rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR);
 313        return 0;
 314}
 315#endif
 316
 317static SIMPLE_DEV_PM_OPS(stmp3xxx_rtc_pm_ops, stmp3xxx_rtc_suspend,
 318                        stmp3xxx_rtc_resume);
 319
 320static const struct of_device_id rtc_dt_ids[] = {
 321        { .compatible = "fsl,stmp3xxx-rtc", },
 322        { /* sentinel */ }
 323};
 324MODULE_DEVICE_TABLE(of, rtc_dt_ids);
 325
 326static struct platform_driver stmp3xxx_rtcdrv = {
 327        .probe          = stmp3xxx_rtc_probe,
 328        .remove         = stmp3xxx_rtc_remove,
 329        .driver         = {
 330                .name   = "stmp3xxx-rtc",
 331                .owner  = THIS_MODULE,
 332                .pm     = &stmp3xxx_rtc_pm_ops,
 333                .of_match_table = of_match_ptr(rtc_dt_ids),
 334        },
 335};
 336
 337module_platform_driver(stmp3xxx_rtcdrv);
 338
 339MODULE_DESCRIPTION("STMP3xxx RTC Driver");
 340MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and "
 341                "Wolfram Sang <w.sang@pengutronix.de>");
 342MODULE_LICENSE("GPL");
 343
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.