root/drivers/rtc/rtc-mxc_v2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mxc_rtc_sync_lp_locked
  2. mxc_rtc_interrupt
  3. mxc_rtc_lock
  4. mxc_rtc_unlock
  5. mxc_rtc_read_time
  6. mxc_rtc_set_time
  7. mxc_rtc_read_alarm
  8. mxc_rtc_alarm_irq_enable_locked
  9. mxc_rtc_alarm_irq_enable
  10. mxc_rtc_set_alarm
  11. mxc_rtc_wait_for_flag
  12. mxc_rtc_probe
  13. mxc_rtc_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Real Time Clock (RTC) Driver for i.MX53
   4  * Copyright (c) 2004-2011 Freescale Semiconductor, Inc.
   5  * Copyright (c) 2017 Beckhoff Automation GmbH & Co. KG
   6  */
   7 
   8 #include <linux/clk.h>
   9 #include <linux/io.h>
  10 #include <linux/module.h>
  11 #include <linux/mod_devicetable.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/pm_wakeirq.h>
  14 #include <linux/rtc.h>
  15 
  16 #define SRTC_LPPDR_INIT       0x41736166        /* init for glitch detect */
  17 
  18 #define SRTC_LPCR_EN_LP       BIT(3)    /* lp enable */
  19 #define SRTC_LPCR_WAE         BIT(4)    /* lp wakeup alarm enable */
  20 #define SRTC_LPCR_ALP         BIT(7)    /* lp alarm flag */
  21 #define SRTC_LPCR_NSA         BIT(11)   /* lp non secure access */
  22 #define SRTC_LPCR_NVE         BIT(14)   /* lp non valid state exit bit */
  23 #define SRTC_LPCR_IE          BIT(15)   /* lp init state exit bit */
  24 
  25 #define SRTC_LPSR_ALP         BIT(3)    /* lp alarm flag */
  26 #define SRTC_LPSR_NVES        BIT(14)   /* lp non-valid state exit status */
  27 #define SRTC_LPSR_IES         BIT(15)   /* lp init state exit status */
  28 
  29 #define SRTC_LPSCMR     0x00    /* LP Secure Counter MSB Reg */
  30 #define SRTC_LPSCLR     0x04    /* LP Secure Counter LSB Reg */
  31 #define SRTC_LPSAR      0x08    /* LP Secure Alarm Reg */
  32 #define SRTC_LPCR       0x10    /* LP Control Reg */
  33 #define SRTC_LPSR       0x14    /* LP Status Reg */
  34 #define SRTC_LPPDR      0x18    /* LP Power Supply Glitch Detector Reg */
  35 
  36 /* max. number of retries to read registers, 120 was max during test */
  37 #define REG_READ_TIMEOUT 2000
  38 
  39 struct mxc_rtc_data {
  40         struct rtc_device *rtc;
  41         void __iomem *ioaddr;
  42         struct clk *clk;
  43         spinlock_t lock; /* protects register access */
  44         int irq;
  45 };
  46 
  47 /*
  48  * This function does write synchronization for writes to the lp srtc block.
  49  * To take care of the asynchronous CKIL clock, all writes from the IP domain
  50  * will be synchronized to the CKIL domain.
  51  * The caller should hold the pdata->lock
  52  */
  53 static void mxc_rtc_sync_lp_locked(struct device *dev, void __iomem *ioaddr)
  54 {
  55         unsigned int i;
  56 
  57         /* Wait for 3 CKIL cycles */
  58         for (i = 0; i < 3; i++) {
  59                 const u32 count = readl(ioaddr + SRTC_LPSCLR);
  60                 unsigned int timeout = REG_READ_TIMEOUT;
  61 
  62                 while ((readl(ioaddr + SRTC_LPSCLR)) == count) {
  63                         if (!--timeout) {
  64                                 dev_err_once(dev, "SRTC_LPSCLR stuck! Check your hw.\n");
  65                                 return;
  66                         }
  67                 }
  68         }
  69 }
  70 
  71 /* This function is the RTC interrupt service routine. */
  72 static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
  73 {
  74         struct device *dev = dev_id;
  75         struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
  76         void __iomem *ioaddr = pdata->ioaddr;
  77         unsigned long flags;
  78         u32 lp_status;
  79         u32 lp_cr;
  80 
  81         spin_lock_irqsave(&pdata->lock, flags);
  82         if (clk_enable(pdata->clk)) {
  83                 spin_unlock_irqrestore(&pdata->lock, flags);
  84                 return IRQ_NONE;
  85         }
  86 
  87         lp_status = readl(ioaddr + SRTC_LPSR);
  88         lp_cr = readl(ioaddr + SRTC_LPCR);
  89 
  90         /* update irq data & counter */
  91         if (lp_status & SRTC_LPSR_ALP) {
  92                 if (lp_cr & SRTC_LPCR_ALP)
  93                         rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF);
  94 
  95                 /* disable further lp alarm interrupts */
  96                 lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
  97         }
  98 
  99         /* Update interrupt enables */
 100         writel(lp_cr, ioaddr + SRTC_LPCR);
 101 
 102         /* clear interrupt status */
 103         writel(lp_status, ioaddr + SRTC_LPSR);
 104 
 105         mxc_rtc_sync_lp_locked(dev, ioaddr);
 106         clk_disable(pdata->clk);
 107         spin_unlock_irqrestore(&pdata->lock, flags);
 108         return IRQ_HANDLED;
 109 }
 110 
 111 /*
 112  * Enable clk and aquire spinlock
 113  * @return  0 if successful; non-zero otherwise.
 114  */
 115 static int mxc_rtc_lock(struct mxc_rtc_data *const pdata)
 116 {
 117         int ret;
 118 
 119         spin_lock_irq(&pdata->lock);
 120         ret = clk_enable(pdata->clk);
 121         if (ret) {
 122                 spin_unlock_irq(&pdata->lock);
 123                 return ret;
 124         }
 125         return 0;
 126 }
 127 
 128 static int mxc_rtc_unlock(struct mxc_rtc_data *const pdata)
 129 {
 130         clk_disable(pdata->clk);
 131         spin_unlock_irq(&pdata->lock);
 132         return 0;
 133 }
 134 
 135 /*
 136  * This function reads the current RTC time into tm in Gregorian date.
 137  *
 138  * @param  tm           contains the RTC time value upon return
 139  *
 140  * @return  0 if successful; non-zero otherwise.
 141  */
 142 static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
 143 {
 144         struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
 145         const int clk_failed = clk_enable(pdata->clk);
 146 
 147         if (!clk_failed) {
 148                 const time64_t now = readl(pdata->ioaddr + SRTC_LPSCMR);
 149 
 150                 rtc_time64_to_tm(now, tm);
 151                 clk_disable(pdata->clk);
 152                 return 0;
 153         }
 154         return clk_failed;
 155 }
 156 
 157 /*
 158  * This function sets the internal RTC time based on tm in Gregorian date.
 159  *
 160  * @param  tm           the time value to be set in the RTC
 161  *
 162  * @return  0 if successful; non-zero otherwise.
 163  */
 164 static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm)
 165 {
 166         struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
 167         time64_t time = rtc_tm_to_time64(tm);
 168         int ret;
 169 
 170         ret = mxc_rtc_lock(pdata);
 171         if (ret)
 172                 return ret;
 173 
 174         writel(time, pdata->ioaddr + SRTC_LPSCMR);
 175         mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
 176         return mxc_rtc_unlock(pdata);
 177 }
 178 
 179 /*
 180  * This function reads the current alarm value into the passed in \b alrm
 181  * argument. It updates the \b alrm's pending field value based on the whether
 182  * an alarm interrupt occurs or not.
 183  *
 184  * @param  alrm         contains the RTC alarm value upon return
 185  *
 186  * @return  0 if successful; non-zero otherwise.
 187  */
 188 static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 189 {
 190         struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
 191         void __iomem *ioaddr = pdata->ioaddr;
 192         int ret;
 193 
 194         ret = mxc_rtc_lock(pdata);
 195         if (ret)
 196                 return ret;
 197 
 198         rtc_time64_to_tm(readl(ioaddr + SRTC_LPSAR), &alrm->time);
 199         alrm->pending = !!(readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_ALP);
 200         return mxc_rtc_unlock(pdata);
 201 }
 202 
 203 /*
 204  * Enable/Disable alarm interrupt
 205  * The caller should hold the pdata->lock
 206  */
 207 static void mxc_rtc_alarm_irq_enable_locked(struct mxc_rtc_data *pdata,
 208                                             unsigned int enable)
 209 {
 210         u32 lp_cr = readl(pdata->ioaddr + SRTC_LPCR);
 211 
 212         if (enable)
 213                 lp_cr |= (SRTC_LPCR_ALP | SRTC_LPCR_WAE);
 214         else
 215                 lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
 216 
 217         writel(lp_cr, pdata->ioaddr + SRTC_LPCR);
 218 }
 219 
 220 static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
 221 {
 222         struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
 223         int ret = mxc_rtc_lock(pdata);
 224 
 225         if (ret)
 226                 return ret;
 227 
 228         mxc_rtc_alarm_irq_enable_locked(pdata, enable);
 229         return mxc_rtc_unlock(pdata);
 230 }
 231 
 232 /*
 233  * This function sets the RTC alarm based on passed in alrm.
 234  *
 235  * @param  alrm         the alarm value to be set in the RTC
 236  *
 237  * @return  0 if successful; non-zero otherwise.
 238  */
 239 static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 240 {
 241         const time64_t time = rtc_tm_to_time64(&alrm->time);
 242         struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
 243         int ret = mxc_rtc_lock(pdata);
 244 
 245         if (ret)
 246                 return ret;
 247 
 248         writel((u32)time, pdata->ioaddr + SRTC_LPSAR);
 249 
 250         /* clear alarm interrupt status bit */
 251         writel(SRTC_LPSR_ALP, pdata->ioaddr + SRTC_LPSR);
 252         mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
 253 
 254         mxc_rtc_alarm_irq_enable_locked(pdata, alrm->enabled);
 255         mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
 256         mxc_rtc_unlock(pdata);
 257         return ret;
 258 }
 259 
 260 static const struct rtc_class_ops mxc_rtc_ops = {
 261         .read_time = mxc_rtc_read_time,
 262         .set_time = mxc_rtc_set_time,
 263         .read_alarm = mxc_rtc_read_alarm,
 264         .set_alarm = mxc_rtc_set_alarm,
 265         .alarm_irq_enable = mxc_rtc_alarm_irq_enable,
 266 };
 267 
 268 static int mxc_rtc_wait_for_flag(void __iomem *ioaddr, int flag)
 269 {
 270         unsigned int timeout = REG_READ_TIMEOUT;
 271 
 272         while (!(readl(ioaddr) & flag)) {
 273                 if (!--timeout)
 274                         return -EBUSY;
 275         }
 276         return 0;
 277 }
 278 
 279 static int mxc_rtc_probe(struct platform_device *pdev)
 280 {
 281         struct mxc_rtc_data *pdata;
 282         void __iomem *ioaddr;
 283         int ret = 0;
 284 
 285         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 286         if (!pdata)
 287                 return -ENOMEM;
 288 
 289         pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
 290         if (IS_ERR(pdata->ioaddr))
 291                 return PTR_ERR(pdata->ioaddr);
 292 
 293         ioaddr = pdata->ioaddr;
 294 
 295         pdata->clk = devm_clk_get(&pdev->dev, NULL);
 296         if (IS_ERR(pdata->clk)) {
 297                 dev_err(&pdev->dev, "unable to get rtc clock!\n");
 298                 return PTR_ERR(pdata->clk);
 299         }
 300 
 301         spin_lock_init(&pdata->lock);
 302         pdata->irq = platform_get_irq(pdev, 0);
 303         if (pdata->irq < 0)
 304                 return pdata->irq;
 305 
 306         device_init_wakeup(&pdev->dev, 1);
 307         ret = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);
 308         if (ret)
 309                 dev_err(&pdev->dev, "failed to enable irq wake\n");
 310 
 311         ret = clk_prepare_enable(pdata->clk);
 312         if (ret)
 313                 return ret;
 314         /* initialize glitch detect */
 315         writel(SRTC_LPPDR_INIT, ioaddr + SRTC_LPPDR);
 316 
 317         /* clear lp interrupt status */
 318         writel(0xFFFFFFFF, ioaddr + SRTC_LPSR);
 319 
 320         /* move out of init state */
 321         writel((SRTC_LPCR_IE | SRTC_LPCR_NSA), ioaddr + SRTC_LPCR);
 322         ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_IES);
 323         if (ret) {
 324                 dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_IES\n");
 325                 clk_disable_unprepare(pdata->clk);
 326                 return ret;
 327         }
 328 
 329         /* move out of non-valid state */
 330         writel((SRTC_LPCR_IE | SRTC_LPCR_NVE | SRTC_LPCR_NSA |
 331                 SRTC_LPCR_EN_LP), ioaddr + SRTC_LPCR);
 332         ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_NVES);
 333         if (ret) {
 334                 dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_NVES\n");
 335                 clk_disable_unprepare(pdata->clk);
 336                 return ret;
 337         }
 338 
 339         pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
 340         if (IS_ERR(pdata->rtc))
 341                 return PTR_ERR(pdata->rtc);
 342 
 343         pdata->rtc->ops = &mxc_rtc_ops;
 344         pdata->rtc->range_max = U32_MAX;
 345 
 346         clk_disable(pdata->clk);
 347         platform_set_drvdata(pdev, pdata);
 348         ret =
 349             devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt, 0,
 350                              pdev->name, &pdev->dev);
 351         if (ret < 0) {
 352                 dev_err(&pdev->dev, "interrupt not available.\n");
 353                 clk_unprepare(pdata->clk);
 354                 return ret;
 355         }
 356 
 357         ret = rtc_register_device(pdata->rtc);
 358         if (ret < 0)
 359                 clk_unprepare(pdata->clk);
 360 
 361         return ret;
 362 }
 363 
 364 static int mxc_rtc_remove(struct platform_device *pdev)
 365 {
 366         struct mxc_rtc_data *pdata = platform_get_drvdata(pdev);
 367 
 368         clk_disable_unprepare(pdata->clk);
 369         return 0;
 370 }
 371 
 372 static const struct of_device_id mxc_ids[] = {
 373         { .compatible = "fsl,imx53-rtc", },
 374         {}
 375 };
 376 
 377 static struct platform_driver mxc_rtc_driver = {
 378         .driver = {
 379                 .name = "mxc_rtc_v2",
 380                 .of_match_table = mxc_ids,
 381         },
 382         .probe = mxc_rtc_probe,
 383         .remove = mxc_rtc_remove,
 384 };
 385 
 386 module_platform_driver(mxc_rtc_driver);
 387 
 388 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 389 MODULE_DESCRIPTION("Real Time Clock (RTC) Driver for i.MX53");
 390 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */