Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
0004  * Copyright 2010 Orex Computed Radiography
0005  */
0006 
0007 /*
0008  * This driver uses the 47-bit 32 kHz counter in the Freescale DryIce block
0009  * to implement a Linux RTC. Times and alarms are truncated to seconds.
0010  * Since the RTC framework performs API locking via rtc->ops_lock the
0011  * only simultaneous accesses we need to deal with is updating DryIce
0012  * registers while servicing an alarm.
0013  *
0014  * Note that reading the DSR (DryIce Status Register) automatically clears
0015  * the WCF (Write Complete Flag). All DryIce writes are synchronized to the
0016  * LP (Low Power) domain and set the WCF upon completion. Writes to the
0017  * DIER (DryIce Interrupt Enable Register) are the only exception. These
0018  * occur at normal bus speeds and do not set WCF.  Periodic interrupts are
0019  * not supported by the hardware.
0020  */
0021 
0022 #include <linux/io.h>
0023 #include <linux/clk.h>
0024 #include <linux/delay.h>
0025 #include <linux/module.h>
0026 #include <linux/platform_device.h>
0027 #include <linux/pm_wakeirq.h>
0028 #include <linux/rtc.h>
0029 #include <linux/sched.h>
0030 #include <linux/spinlock.h>
0031 #include <linux/workqueue.h>
0032 #include <linux/of.h>
0033 
0034 /* DryIce Register Definitions */
0035 
0036 #define DTCMR     0x00           /* Time Counter MSB Reg */
0037 #define DTCLR     0x04           /* Time Counter LSB Reg */
0038 
0039 #define DCAMR     0x08           /* Clock Alarm MSB Reg */
0040 #define DCALR     0x0c           /* Clock Alarm LSB Reg */
0041 #define DCAMR_UNSET  0xFFFFFFFF  /* doomsday - 1 sec */
0042 
0043 #define DCR       0x10           /* Control Reg */
0044 #define DCR_TDCHL (1 << 30)      /* Tamper-detect configuration hard lock */
0045 #define DCR_TDCSL (1 << 29)      /* Tamper-detect configuration soft lock */
0046 #define DCR_KSSL  (1 << 27)      /* Key-select soft lock */
0047 #define DCR_MCHL  (1 << 20)      /* Monotonic-counter hard lock */
0048 #define DCR_MCSL  (1 << 19)      /* Monotonic-counter soft lock */
0049 #define DCR_TCHL  (1 << 18)      /* Timer-counter hard lock */
0050 #define DCR_TCSL  (1 << 17)      /* Timer-counter soft lock */
0051 #define DCR_FSHL  (1 << 16)      /* Failure state hard lock */
0052 #define DCR_TCE   (1 << 3)       /* Time Counter Enable */
0053 #define DCR_MCE   (1 << 2)       /* Monotonic Counter Enable */
0054 
0055 #define DSR       0x14           /* Status Reg */
0056 #define DSR_WTD   (1 << 23)      /* Wire-mesh tamper detected */
0057 #define DSR_ETBD  (1 << 22)      /* External tamper B detected */
0058 #define DSR_ETAD  (1 << 21)      /* External tamper A detected */
0059 #define DSR_EBD   (1 << 20)      /* External boot detected */
0060 #define DSR_SAD   (1 << 19)      /* SCC alarm detected */
0061 #define DSR_TTD   (1 << 18)      /* Temperature tamper detected */
0062 #define DSR_CTD   (1 << 17)      /* Clock tamper detected */
0063 #define DSR_VTD   (1 << 16)      /* Voltage tamper detected */
0064 #define DSR_WBF   (1 << 10)      /* Write Busy Flag (synchronous) */
0065 #define DSR_WNF   (1 << 9)       /* Write Next Flag (synchronous) */
0066 #define DSR_WCF   (1 << 8)       /* Write Complete Flag (synchronous)*/
0067 #define DSR_WEF   (1 << 7)       /* Write Error Flag */
0068 #define DSR_CAF   (1 << 4)       /* Clock Alarm Flag */
0069 #define DSR_MCO   (1 << 3)       /* monotonic counter overflow */
0070 #define DSR_TCO   (1 << 2)       /* time counter overflow */
0071 #define DSR_NVF   (1 << 1)       /* Non-Valid Flag */
0072 #define DSR_SVF   (1 << 0)       /* Security Violation Flag */
0073 
0074 #define DIER      0x18           /* Interrupt Enable Reg (synchronous) */
0075 #define DIER_WNIE (1 << 9)       /* Write Next Interrupt Enable */
0076 #define DIER_WCIE (1 << 8)       /* Write Complete Interrupt Enable */
0077 #define DIER_WEIE (1 << 7)       /* Write Error Interrupt Enable */
0078 #define DIER_CAIE (1 << 4)       /* Clock Alarm Interrupt Enable */
0079 #define DIER_SVIE (1 << 0)       /* Security-violation Interrupt Enable */
0080 
0081 #define DMCR      0x1c           /* DryIce Monotonic Counter Reg */
0082 
0083 #define DTCR      0x28           /* DryIce Tamper Configuration Reg */
0084 #define DTCR_MOE  (1 << 9)       /* monotonic overflow enabled */
0085 #define DTCR_TOE  (1 << 8)       /* time overflow enabled */
0086 #define DTCR_WTE  (1 << 7)       /* wire-mesh tamper enabled */
0087 #define DTCR_ETBE (1 << 6)       /* external B tamper enabled */
0088 #define DTCR_ETAE (1 << 5)       /* external A tamper enabled */
0089 #define DTCR_EBE  (1 << 4)       /* external boot tamper enabled */
0090 #define DTCR_SAIE (1 << 3)       /* SCC enabled */
0091 #define DTCR_TTE  (1 << 2)       /* temperature tamper enabled */
0092 #define DTCR_CTE  (1 << 1)       /* clock tamper enabled */
0093 #define DTCR_VTE  (1 << 0)       /* voltage tamper enabled */
0094 
0095 #define DGPR      0x3c           /* DryIce General Purpose Reg */
0096 
0097 /**
0098  * struct imxdi_dev - private imxdi rtc data
0099  * @pdev: pointer to platform dev
0100  * @rtc: pointer to rtc struct
0101  * @ioaddr: IO registers pointer
0102  * @clk: input reference clock
0103  * @dsr: copy of the DSR register
0104  * @irq_lock: interrupt enable register (DIER) lock
0105  * @write_wait: registers write complete queue
0106  * @write_mutex: serialize registers write
0107  * @work: schedule alarm work
0108  */
0109 struct imxdi_dev {
0110     struct platform_device *pdev;
0111     struct rtc_device *rtc;
0112     void __iomem *ioaddr;
0113     struct clk *clk;
0114     u32 dsr;
0115     spinlock_t irq_lock;
0116     wait_queue_head_t write_wait;
0117     struct mutex write_mutex;
0118     struct work_struct work;
0119 };
0120 
0121 /* Some background:
0122  *
0123  * The DryIce unit is a complex security/tamper monitor device. To be able do
0124  * its job in a useful manner it runs a bigger statemachine to bring it into
0125  * security/tamper failure state and once again to bring it out of this state.
0126  *
0127  * This unit can be in one of three states:
0128  *
0129  * - "NON-VALID STATE"
0130  *   always after the battery power was removed
0131  * - "FAILURE STATE"
0132  *   if one of the enabled security events has happened
0133  * - "VALID STATE"
0134  *   if the unit works as expected
0135  *
0136  * Everything stops when the unit enters the failure state including the RTC
0137  * counter (to be able to detect the time the security event happened).
0138  *
0139  * The following events (when enabled) let the DryIce unit enter the failure
0140  * state:
0141  *
0142  * - wire-mesh-tamper detect
0143  * - external tamper B detect
0144  * - external tamper A detect
0145  * - temperature tamper detect
0146  * - clock tamper detect
0147  * - voltage tamper detect
0148  * - RTC counter overflow
0149  * - monotonic counter overflow
0150  * - external boot
0151  *
0152  * If we find the DryIce unit in "FAILURE STATE" and the TDCHL cleared, we
0153  * can only detect this state. In this case the unit is completely locked and
0154  * must force a second "SYSTEM POR" to bring the DryIce into the
0155  * "NON-VALID STATE" + "FAILURE STATE" where a recovery is possible.
0156  * If the TDCHL is set in the "FAILURE STATE" we are out of luck. In this case
0157  * a battery power cycle is required.
0158  *
0159  * In the "NON-VALID STATE" + "FAILURE STATE" we can clear the "FAILURE STATE"
0160  * and recover the DryIce unit. By clearing the "NON-VALID STATE" as the last
0161  * task, we bring back this unit into life.
0162  */
0163 
0164 /*
0165  * Do a write into the unit without interrupt support.
0166  * We do not need to check the WEF here, because the only reason this kind of
0167  * write error can happen is if we write to the unit twice within the 122 us
0168  * interval. This cannot happen, since we are using this function only while
0169  * setting up the unit.
0170  */
0171 static void di_write_busy_wait(const struct imxdi_dev *imxdi, u32 val,
0172                    unsigned reg)
0173 {
0174     /* do the register write */
0175     writel(val, imxdi->ioaddr + reg);
0176 
0177     /*
0178      * now it takes four 32,768 kHz clock cycles to take
0179      * the change into effect = 122 us
0180      */
0181     usleep_range(130, 200);
0182 }
0183 
0184 static void di_report_tamper_info(struct imxdi_dev *imxdi,  u32 dsr)
0185 {
0186     u32 dtcr;
0187 
0188     dtcr = readl(imxdi->ioaddr + DTCR);
0189 
0190     dev_emerg(&imxdi->pdev->dev, "DryIce tamper event detected\n");
0191     /* the following flags force a transition into the "FAILURE STATE" */
0192     if (dsr & DSR_VTD)
0193         dev_emerg(&imxdi->pdev->dev, "%sVoltage Tamper Event\n",
0194               dtcr & DTCR_VTE ? "" : "Spurious ");
0195 
0196     if (dsr & DSR_CTD)
0197         dev_emerg(&imxdi->pdev->dev, "%s32768 Hz Clock Tamper Event\n",
0198               dtcr & DTCR_CTE ? "" : "Spurious ");
0199 
0200     if (dsr & DSR_TTD)
0201         dev_emerg(&imxdi->pdev->dev, "%sTemperature Tamper Event\n",
0202               dtcr & DTCR_TTE ? "" : "Spurious ");
0203 
0204     if (dsr & DSR_SAD)
0205         dev_emerg(&imxdi->pdev->dev,
0206               "%sSecure Controller Alarm Event\n",
0207               dtcr & DTCR_SAIE ? "" : "Spurious ");
0208 
0209     if (dsr & DSR_EBD)
0210         dev_emerg(&imxdi->pdev->dev, "%sExternal Boot Tamper Event\n",
0211               dtcr & DTCR_EBE ? "" : "Spurious ");
0212 
0213     if (dsr & DSR_ETAD)
0214         dev_emerg(&imxdi->pdev->dev, "%sExternal Tamper A Event\n",
0215               dtcr & DTCR_ETAE ? "" : "Spurious ");
0216 
0217     if (dsr & DSR_ETBD)
0218         dev_emerg(&imxdi->pdev->dev, "%sExternal Tamper B Event\n",
0219               dtcr & DTCR_ETBE ? "" : "Spurious ");
0220 
0221     if (dsr & DSR_WTD)
0222         dev_emerg(&imxdi->pdev->dev, "%sWire-mesh Tamper Event\n",
0223               dtcr & DTCR_WTE ? "" : "Spurious ");
0224 
0225     if (dsr & DSR_MCO)
0226         dev_emerg(&imxdi->pdev->dev,
0227               "%sMonotonic-counter Overflow Event\n",
0228               dtcr & DTCR_MOE ? "" : "Spurious ");
0229 
0230     if (dsr & DSR_TCO)
0231         dev_emerg(&imxdi->pdev->dev, "%sTimer-counter Overflow Event\n",
0232               dtcr & DTCR_TOE ? "" : "Spurious ");
0233 }
0234 
0235 static void di_what_is_to_be_done(struct imxdi_dev *imxdi,
0236                   const char *power_supply)
0237 {
0238     dev_emerg(&imxdi->pdev->dev, "Please cycle the %s power supply in order to get the DryIce/RTC unit working again\n",
0239           power_supply);
0240 }
0241 
0242 static int di_handle_failure_state(struct imxdi_dev *imxdi, u32 dsr)
0243 {
0244     u32 dcr;
0245 
0246     dev_dbg(&imxdi->pdev->dev, "DSR register reports: %08X\n", dsr);
0247 
0248     /* report the cause */
0249     di_report_tamper_info(imxdi, dsr);
0250 
0251     dcr = readl(imxdi->ioaddr + DCR);
0252 
0253     if (dcr & DCR_FSHL) {
0254         /* we are out of luck */
0255         di_what_is_to_be_done(imxdi, "battery");
0256         return -ENODEV;
0257     }
0258     /*
0259      * with the next SYSTEM POR we will transit from the "FAILURE STATE"
0260      * into the "NON-VALID STATE" + "FAILURE STATE"
0261      */
0262     di_what_is_to_be_done(imxdi, "main");
0263 
0264     return -ENODEV;
0265 }
0266 
0267 static int di_handle_valid_state(struct imxdi_dev *imxdi, u32 dsr)
0268 {
0269     /* initialize alarm */
0270     di_write_busy_wait(imxdi, DCAMR_UNSET, DCAMR);
0271     di_write_busy_wait(imxdi, 0, DCALR);
0272 
0273     /* clear alarm flag */
0274     if (dsr & DSR_CAF)
0275         di_write_busy_wait(imxdi, DSR_CAF, DSR);
0276 
0277     return 0;
0278 }
0279 
0280 static int di_handle_invalid_state(struct imxdi_dev *imxdi, u32 dsr)
0281 {
0282     u32 dcr, sec;
0283 
0284     /*
0285      * lets disable all sources which can force the DryIce unit into
0286      * the "FAILURE STATE" for now
0287      */
0288     di_write_busy_wait(imxdi, 0x00000000, DTCR);
0289     /* and lets protect them at runtime from any change */
0290     di_write_busy_wait(imxdi, DCR_TDCSL, DCR);
0291 
0292     sec = readl(imxdi->ioaddr + DTCMR);
0293     if (sec != 0)
0294         dev_warn(&imxdi->pdev->dev,
0295              "The security violation has happened at %u seconds\n",
0296              sec);
0297     /*
0298      * the timer cannot be set/modified if
0299      * - the TCHL or TCSL bit is set in DCR
0300      */
0301     dcr = readl(imxdi->ioaddr + DCR);
0302     if (!(dcr & DCR_TCE)) {
0303         if (dcr & DCR_TCHL) {
0304             /* we are out of luck */
0305             di_what_is_to_be_done(imxdi, "battery");
0306             return -ENODEV;
0307         }
0308         if (dcr & DCR_TCSL) {
0309             di_what_is_to_be_done(imxdi, "main");
0310             return -ENODEV;
0311         }
0312     }
0313     /*
0314      * - the timer counter stops/is stopped if
0315      *   - its overflow flag is set (TCO in DSR)
0316      *      -> clear overflow bit to make it count again
0317      *   - NVF is set in DSR
0318      *      -> clear non-valid bit to make it count again
0319      *   - its TCE (DCR) is cleared
0320      *      -> set TCE to make it count
0321      *   - it was never set before
0322      *      -> write a time into it (required again if the NVF was set)
0323      */
0324     /* state handled */
0325     di_write_busy_wait(imxdi, DSR_NVF, DSR);
0326     /* clear overflow flag */
0327     di_write_busy_wait(imxdi, DSR_TCO, DSR);
0328     /* enable the counter */
0329     di_write_busy_wait(imxdi, dcr | DCR_TCE, DCR);
0330     /* set and trigger it to make it count */
0331     di_write_busy_wait(imxdi, sec, DTCMR);
0332 
0333     /* now prepare for the valid state */
0334     return di_handle_valid_state(imxdi, __raw_readl(imxdi->ioaddr + DSR));
0335 }
0336 
0337 static int di_handle_invalid_and_failure_state(struct imxdi_dev *imxdi, u32 dsr)
0338 {
0339     u32 dcr;
0340 
0341     /*
0342      * now we must first remove the tamper sources in order to get the
0343      * device out of the "FAILURE STATE"
0344      * To disable any of the following sources we need to modify the DTCR
0345      */
0346     if (dsr & (DSR_WTD | DSR_ETBD | DSR_ETAD | DSR_EBD | DSR_SAD |
0347             DSR_TTD | DSR_CTD | DSR_VTD | DSR_MCO | DSR_TCO)) {
0348         dcr = __raw_readl(imxdi->ioaddr + DCR);
0349         if (dcr & DCR_TDCHL) {
0350             /*
0351              * the tamper register is locked. We cannot disable the
0352              * tamper detection. The TDCHL can only be reset by a
0353              * DRYICE POR, but we cannot force a DRYICE POR in
0354              * software because we are still in "FAILURE STATE".
0355              * We need a DRYICE POR via battery power cycling....
0356              */
0357             /*
0358              * out of luck!
0359              * we cannot disable them without a DRYICE POR
0360              */
0361             di_what_is_to_be_done(imxdi, "battery");
0362             return -ENODEV;
0363         }
0364         if (dcr & DCR_TDCSL) {
0365             /* a soft lock can be removed by a SYSTEM POR */
0366             di_what_is_to_be_done(imxdi, "main");
0367             return -ENODEV;
0368         }
0369     }
0370 
0371     /* disable all sources */
0372     di_write_busy_wait(imxdi, 0x00000000, DTCR);
0373 
0374     /* clear the status bits now */
0375     di_write_busy_wait(imxdi, dsr & (DSR_WTD | DSR_ETBD | DSR_ETAD |
0376             DSR_EBD | DSR_SAD | DSR_TTD | DSR_CTD | DSR_VTD |
0377             DSR_MCO | DSR_TCO), DSR);
0378 
0379     dsr = readl(imxdi->ioaddr + DSR);
0380     if ((dsr & ~(DSR_NVF | DSR_SVF | DSR_WBF | DSR_WNF |
0381             DSR_WCF | DSR_WEF)) != 0)
0382         dev_warn(&imxdi->pdev->dev,
0383              "There are still some sources of pain in DSR: %08x!\n",
0384              dsr & ~(DSR_NVF | DSR_SVF | DSR_WBF | DSR_WNF |
0385                  DSR_WCF | DSR_WEF));
0386 
0387     /*
0388      * now we are trying to clear the "Security-violation flag" to
0389      * get the DryIce out of this state
0390      */
0391     di_write_busy_wait(imxdi, DSR_SVF, DSR);
0392 
0393     /* success? */
0394     dsr = readl(imxdi->ioaddr + DSR);
0395     if (dsr & DSR_SVF) {
0396         dev_crit(&imxdi->pdev->dev,
0397              "Cannot clear the security violation flag. We are ending up in an endless loop!\n");
0398         /* last resort */
0399         di_what_is_to_be_done(imxdi, "battery");
0400         return -ENODEV;
0401     }
0402 
0403     /*
0404      * now we have left the "FAILURE STATE" and ending up in the
0405      * "NON-VALID STATE" time to recover everything
0406      */
0407     return di_handle_invalid_state(imxdi, dsr);
0408 }
0409 
0410 static int di_handle_state(struct imxdi_dev *imxdi)
0411 {
0412     int rc;
0413     u32 dsr;
0414 
0415     dsr = readl(imxdi->ioaddr + DSR);
0416 
0417     switch (dsr & (DSR_NVF | DSR_SVF)) {
0418     case DSR_NVF:
0419         dev_warn(&imxdi->pdev->dev, "Invalid stated unit detected\n");
0420         rc = di_handle_invalid_state(imxdi, dsr);
0421         break;
0422     case DSR_SVF:
0423         dev_warn(&imxdi->pdev->dev, "Failure stated unit detected\n");
0424         rc = di_handle_failure_state(imxdi, dsr);
0425         break;
0426     case DSR_NVF | DSR_SVF:
0427         dev_warn(&imxdi->pdev->dev,
0428              "Failure+Invalid stated unit detected\n");
0429         rc = di_handle_invalid_and_failure_state(imxdi, dsr);
0430         break;
0431     default:
0432         dev_notice(&imxdi->pdev->dev, "Unlocked unit detected\n");
0433         rc = di_handle_valid_state(imxdi, dsr);
0434     }
0435 
0436     return rc;
0437 }
0438 
0439 /*
0440  * enable a dryice interrupt
0441  */
0442 static void di_int_enable(struct imxdi_dev *imxdi, u32 intr)
0443 {
0444     unsigned long flags;
0445 
0446     spin_lock_irqsave(&imxdi->irq_lock, flags);
0447     writel(readl(imxdi->ioaddr + DIER) | intr,
0448            imxdi->ioaddr + DIER);
0449     spin_unlock_irqrestore(&imxdi->irq_lock, flags);
0450 }
0451 
0452 /*
0453  * disable a dryice interrupt
0454  */
0455 static void di_int_disable(struct imxdi_dev *imxdi, u32 intr)
0456 {
0457     unsigned long flags;
0458 
0459     spin_lock_irqsave(&imxdi->irq_lock, flags);
0460     writel(readl(imxdi->ioaddr + DIER) & ~intr,
0461            imxdi->ioaddr + DIER);
0462     spin_unlock_irqrestore(&imxdi->irq_lock, flags);
0463 }
0464 
0465 /*
0466  * This function attempts to clear the dryice write-error flag.
0467  *
0468  * A dryice write error is similar to a bus fault and should not occur in
0469  * normal operation.  Clearing the flag requires another write, so the root
0470  * cause of the problem may need to be fixed before the flag can be cleared.
0471  */
0472 static void clear_write_error(struct imxdi_dev *imxdi)
0473 {
0474     int cnt;
0475 
0476     dev_warn(&imxdi->pdev->dev, "WARNING: Register write error!\n");
0477 
0478     /* clear the write error flag */
0479     writel(DSR_WEF, imxdi->ioaddr + DSR);
0480 
0481     /* wait for it to take effect */
0482     for (cnt = 0; cnt < 1000; cnt++) {
0483         if ((readl(imxdi->ioaddr + DSR) & DSR_WEF) == 0)
0484             return;
0485         udelay(10);
0486     }
0487     dev_err(&imxdi->pdev->dev,
0488             "ERROR: Cannot clear write-error flag!\n");
0489 }
0490 
0491 /*
0492  * Write a dryice register and wait until it completes.
0493  *
0494  * This function uses interrupts to determine when the
0495  * write has completed.
0496  */
0497 static int di_write_wait(struct imxdi_dev *imxdi, u32 val, int reg)
0498 {
0499     int ret;
0500     int rc = 0;
0501 
0502     /* serialize register writes */
0503     mutex_lock(&imxdi->write_mutex);
0504 
0505     /* enable the write-complete interrupt */
0506     di_int_enable(imxdi, DIER_WCIE);
0507 
0508     imxdi->dsr = 0;
0509 
0510     /* do the register write */
0511     writel(val, imxdi->ioaddr + reg);
0512 
0513     /* wait for the write to finish */
0514     ret = wait_event_interruptible_timeout(imxdi->write_wait,
0515             imxdi->dsr & (DSR_WCF | DSR_WEF), msecs_to_jiffies(1));
0516     if (ret < 0) {
0517         rc = ret;
0518         goto out;
0519     } else if (ret == 0) {
0520         dev_warn(&imxdi->pdev->dev,
0521                 "Write-wait timeout "
0522                 "val = 0x%08x reg = 0x%08x\n", val, reg);
0523     }
0524 
0525     /* check for write error */
0526     if (imxdi->dsr & DSR_WEF) {
0527         clear_write_error(imxdi);
0528         rc = -EIO;
0529     }
0530 
0531 out:
0532     mutex_unlock(&imxdi->write_mutex);
0533 
0534     return rc;
0535 }
0536 
0537 /*
0538  * read the seconds portion of the current time from the dryice time counter
0539  */
0540 static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm)
0541 {
0542     struct imxdi_dev *imxdi = dev_get_drvdata(dev);
0543     unsigned long now;
0544 
0545     now = readl(imxdi->ioaddr + DTCMR);
0546     rtc_time64_to_tm(now, tm);
0547 
0548     return 0;
0549 }
0550 
0551 /*
0552  * set the seconds portion of dryice time counter and clear the
0553  * fractional part.
0554  */
0555 static int dryice_rtc_set_time(struct device *dev, struct rtc_time *tm)
0556 {
0557     struct imxdi_dev *imxdi = dev_get_drvdata(dev);
0558     u32 dcr, dsr;
0559     int rc;
0560 
0561     dcr = readl(imxdi->ioaddr + DCR);
0562     dsr = readl(imxdi->ioaddr + DSR);
0563 
0564     if (!(dcr & DCR_TCE) || (dsr & DSR_SVF)) {
0565         if (dcr & DCR_TCHL) {
0566             /* we are even more out of luck */
0567             di_what_is_to_be_done(imxdi, "battery");
0568             return -EPERM;
0569         }
0570         if ((dcr & DCR_TCSL) || (dsr & DSR_SVF)) {
0571             /* we are out of luck for now */
0572             di_what_is_to_be_done(imxdi, "main");
0573             return -EPERM;
0574         }
0575     }
0576 
0577     /* zero the fractional part first */
0578     rc = di_write_wait(imxdi, 0, DTCLR);
0579     if (rc != 0)
0580         return rc;
0581 
0582     rc = di_write_wait(imxdi, rtc_tm_to_time64(tm), DTCMR);
0583     if (rc != 0)
0584         return rc;
0585 
0586     return di_write_wait(imxdi, readl(imxdi->ioaddr + DCR) | DCR_TCE, DCR);
0587 }
0588 
0589 static int dryice_rtc_alarm_irq_enable(struct device *dev,
0590         unsigned int enabled)
0591 {
0592     struct imxdi_dev *imxdi = dev_get_drvdata(dev);
0593 
0594     if (enabled)
0595         di_int_enable(imxdi, DIER_CAIE);
0596     else
0597         di_int_disable(imxdi, DIER_CAIE);
0598 
0599     return 0;
0600 }
0601 
0602 /*
0603  * read the seconds portion of the alarm register.
0604  * the fractional part of the alarm register is always zero.
0605  */
0606 static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0607 {
0608     struct imxdi_dev *imxdi = dev_get_drvdata(dev);
0609     u32 dcamr;
0610 
0611     dcamr = readl(imxdi->ioaddr + DCAMR);
0612     rtc_time64_to_tm(dcamr, &alarm->time);
0613 
0614     /* alarm is enabled if the interrupt is enabled */
0615     alarm->enabled = (readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0;
0616 
0617     /* don't allow the DSR read to mess up DSR_WCF */
0618     mutex_lock(&imxdi->write_mutex);
0619 
0620     /* alarm is pending if the alarm flag is set */
0621     alarm->pending = (readl(imxdi->ioaddr + DSR) & DSR_CAF) != 0;
0622 
0623     mutex_unlock(&imxdi->write_mutex);
0624 
0625     return 0;
0626 }
0627 
0628 /*
0629  * set the seconds portion of dryice alarm register
0630  */
0631 static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0632 {
0633     struct imxdi_dev *imxdi = dev_get_drvdata(dev);
0634     int rc;
0635 
0636     /* write the new alarm time */
0637     rc = di_write_wait(imxdi, rtc_tm_to_time64(&alarm->time), DCAMR);
0638     if (rc)
0639         return rc;
0640 
0641     if (alarm->enabled)
0642         di_int_enable(imxdi, DIER_CAIE);  /* enable alarm intr */
0643     else
0644         di_int_disable(imxdi, DIER_CAIE); /* disable alarm intr */
0645 
0646     return 0;
0647 }
0648 
0649 static const struct rtc_class_ops dryice_rtc_ops = {
0650     .read_time      = dryice_rtc_read_time,
0651     .set_time       = dryice_rtc_set_time,
0652     .alarm_irq_enable   = dryice_rtc_alarm_irq_enable,
0653     .read_alarm     = dryice_rtc_read_alarm,
0654     .set_alarm      = dryice_rtc_set_alarm,
0655 };
0656 
0657 /*
0658  * interrupt handler for dryice "normal" and security violation interrupt
0659  */
0660 static irqreturn_t dryice_irq(int irq, void *dev_id)
0661 {
0662     struct imxdi_dev *imxdi = dev_id;
0663     u32 dsr, dier;
0664     irqreturn_t rc = IRQ_NONE;
0665 
0666     dier = readl(imxdi->ioaddr + DIER);
0667     dsr = readl(imxdi->ioaddr + DSR);
0668 
0669     /* handle the security violation event */
0670     if (dier & DIER_SVIE) {
0671         if (dsr & DSR_SVF) {
0672             /*
0673              * Disable the interrupt when this kind of event has
0674              * happened.
0675              * There cannot be more than one event of this type,
0676              * because it needs a complex state change
0677              * including a main power cycle to get again out of
0678              * this state.
0679              */
0680             di_int_disable(imxdi, DIER_SVIE);
0681             /* report the violation */
0682             di_report_tamper_info(imxdi, dsr);
0683             rc = IRQ_HANDLED;
0684         }
0685     }
0686 
0687     /* handle write complete and write error cases */
0688     if (dier & DIER_WCIE) {
0689         /*If the write wait queue is empty then there is no pending
0690           operations. It means the interrupt is for DryIce -Security.
0691           IRQ must be returned as none.*/
0692         if (list_empty_careful(&imxdi->write_wait.head))
0693             return rc;
0694 
0695         /* DSR_WCF clears itself on DSR read */
0696         if (dsr & (DSR_WCF | DSR_WEF)) {
0697             /* mask the interrupt */
0698             di_int_disable(imxdi, DIER_WCIE);
0699 
0700             /* save the dsr value for the wait queue */
0701             imxdi->dsr |= dsr;
0702 
0703             wake_up_interruptible(&imxdi->write_wait);
0704             rc = IRQ_HANDLED;
0705         }
0706     }
0707 
0708     /* handle the alarm case */
0709     if (dier & DIER_CAIE) {
0710         /* DSR_WCF clears itself on DSR read */
0711         if (dsr & DSR_CAF) {
0712             /* mask the interrupt */
0713             di_int_disable(imxdi, DIER_CAIE);
0714 
0715             /* finish alarm in user context */
0716             schedule_work(&imxdi->work);
0717             rc = IRQ_HANDLED;
0718         }
0719     }
0720     return rc;
0721 }
0722 
0723 /*
0724  * post the alarm event from user context so it can sleep
0725  * on the write completion.
0726  */
0727 static void dryice_work(struct work_struct *work)
0728 {
0729     struct imxdi_dev *imxdi = container_of(work,
0730             struct imxdi_dev, work);
0731 
0732     /* dismiss the interrupt (ignore error) */
0733     di_write_wait(imxdi, DSR_CAF, DSR);
0734 
0735     /* pass the alarm event to the rtc framework. */
0736     rtc_update_irq(imxdi->rtc, 1, RTC_AF | RTC_IRQF);
0737 }
0738 
0739 /*
0740  * probe for dryice rtc device
0741  */
0742 static int __init dryice_rtc_probe(struct platform_device *pdev)
0743 {
0744     struct imxdi_dev *imxdi;
0745     int norm_irq, sec_irq;
0746     int rc;
0747 
0748     imxdi = devm_kzalloc(&pdev->dev, sizeof(*imxdi), GFP_KERNEL);
0749     if (!imxdi)
0750         return -ENOMEM;
0751 
0752     imxdi->pdev = pdev;
0753 
0754     imxdi->ioaddr = devm_platform_ioremap_resource(pdev, 0);
0755     if (IS_ERR(imxdi->ioaddr))
0756         return PTR_ERR(imxdi->ioaddr);
0757 
0758     spin_lock_init(&imxdi->irq_lock);
0759 
0760     norm_irq = platform_get_irq(pdev, 0);
0761     if (norm_irq < 0)
0762         return norm_irq;
0763 
0764     /* the 2nd irq is the security violation irq
0765      * make this optional, don't break the device tree ABI
0766      */
0767     sec_irq = platform_get_irq(pdev, 1);
0768     if (sec_irq <= 0)
0769         sec_irq = IRQ_NOTCONNECTED;
0770 
0771     init_waitqueue_head(&imxdi->write_wait);
0772 
0773     INIT_WORK(&imxdi->work, dryice_work);
0774 
0775     mutex_init(&imxdi->write_mutex);
0776 
0777     imxdi->rtc = devm_rtc_allocate_device(&pdev->dev);
0778     if (IS_ERR(imxdi->rtc))
0779         return PTR_ERR(imxdi->rtc);
0780 
0781     imxdi->clk = devm_clk_get(&pdev->dev, NULL);
0782     if (IS_ERR(imxdi->clk))
0783         return PTR_ERR(imxdi->clk);
0784     rc = clk_prepare_enable(imxdi->clk);
0785     if (rc)
0786         return rc;
0787 
0788     /*
0789      * Initialize dryice hardware
0790      */
0791 
0792     /* mask all interrupts */
0793     writel(0, imxdi->ioaddr + DIER);
0794 
0795     rc = di_handle_state(imxdi);
0796     if (rc != 0)
0797         goto err;
0798 
0799     rc = devm_request_irq(&pdev->dev, norm_irq, dryice_irq,
0800                   IRQF_SHARED, pdev->name, imxdi);
0801     if (rc) {
0802         dev_warn(&pdev->dev, "interrupt not available.\n");
0803         goto err;
0804     }
0805 
0806     rc = devm_request_irq(&pdev->dev, sec_irq, dryice_irq,
0807                   IRQF_SHARED, pdev->name, imxdi);
0808     if (rc) {
0809         dev_warn(&pdev->dev, "security violation interrupt not available.\n");
0810         /* this is not an error, see above */
0811     }
0812 
0813     platform_set_drvdata(pdev, imxdi);
0814 
0815     device_init_wakeup(&pdev->dev, true);
0816     dev_pm_set_wake_irq(&pdev->dev, norm_irq);
0817 
0818     imxdi->rtc->ops = &dryice_rtc_ops;
0819     imxdi->rtc->range_max = U32_MAX;
0820 
0821     rc = devm_rtc_register_device(imxdi->rtc);
0822     if (rc)
0823         goto err;
0824 
0825     return 0;
0826 
0827 err:
0828     clk_disable_unprepare(imxdi->clk);
0829 
0830     return rc;
0831 }
0832 
0833 static int __exit dryice_rtc_remove(struct platform_device *pdev)
0834 {
0835     struct imxdi_dev *imxdi = platform_get_drvdata(pdev);
0836 
0837     flush_work(&imxdi->work);
0838 
0839     /* mask all interrupts */
0840     writel(0, imxdi->ioaddr + DIER);
0841 
0842     clk_disable_unprepare(imxdi->clk);
0843 
0844     return 0;
0845 }
0846 
0847 static const struct of_device_id dryice_dt_ids[] = {
0848     { .compatible = "fsl,imx25-rtc" },
0849     { /* sentinel */ }
0850 };
0851 
0852 MODULE_DEVICE_TABLE(of, dryice_dt_ids);
0853 
0854 static struct platform_driver dryice_rtc_driver = {
0855     .driver = {
0856            .name = "imxdi_rtc",
0857            .of_match_table = dryice_dt_ids,
0858            },
0859     .remove = __exit_p(dryice_rtc_remove),
0860 };
0861 
0862 module_platform_driver_probe(dryice_rtc_driver, dryice_rtc_probe);
0863 
0864 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
0865 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
0866 MODULE_DESCRIPTION("IMX DryIce Realtime Clock Driver (RTC)");
0867 MODULE_LICENSE("GPL");