This source file includes following definitions.
- di_write_busy_wait
- di_report_tamper_info
- di_what_is_to_be_done
- di_handle_failure_state
- di_handle_valid_state
- di_handle_invalid_state
- di_handle_invalid_and_failure_state
- di_handle_state
- di_int_enable
- di_int_disable
- clear_write_error
- di_write_wait
- dryice_rtc_read_time
- dryice_rtc_set_time
- dryice_rtc_alarm_irq_enable
- dryice_rtc_read_alarm
- dryice_rtc_set_alarm
- dryice_irq
- dryice_work
- dryice_rtc_probe
- dryice_rtc_remove
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 #include <linux/io.h>
  23 #include <linux/clk.h>
  24 #include <linux/delay.h>
  25 #include <linux/module.h>
  26 #include <linux/platform_device.h>
  27 #include <linux/rtc.h>
  28 #include <linux/sched.h>
  29 #include <linux/spinlock.h>
  30 #include <linux/workqueue.h>
  31 #include <linux/of.h>
  32 
  33 
  34 
  35 #define DTCMR     0x00           
  36 #define DTCLR     0x04           
  37 
  38 #define DCAMR     0x08           
  39 #define DCALR     0x0c           
  40 #define DCAMR_UNSET  0xFFFFFFFF  
  41 
  42 #define DCR       0x10           
  43 #define DCR_TDCHL (1 << 30)      
  44 #define DCR_TDCSL (1 << 29)      
  45 #define DCR_KSSL  (1 << 27)      
  46 #define DCR_MCHL  (1 << 20)      
  47 #define DCR_MCSL  (1 << 19)      
  48 #define DCR_TCHL  (1 << 18)      
  49 #define DCR_TCSL  (1 << 17)      
  50 #define DCR_FSHL  (1 << 16)      
  51 #define DCR_TCE   (1 << 3)       
  52 #define DCR_MCE   (1 << 2)       
  53 
  54 #define DSR       0x14           
  55 #define DSR_WTD   (1 << 23)      
  56 #define DSR_ETBD  (1 << 22)      
  57 #define DSR_ETAD  (1 << 21)      
  58 #define DSR_EBD   (1 << 20)      
  59 #define DSR_SAD   (1 << 19)      
  60 #define DSR_TTD   (1 << 18)      
  61 #define DSR_CTD   (1 << 17)      
  62 #define DSR_VTD   (1 << 16)      
  63 #define DSR_WBF   (1 << 10)      
  64 #define DSR_WNF   (1 << 9)       
  65 #define DSR_WCF   (1 << 8)       
  66 #define DSR_WEF   (1 << 7)       
  67 #define DSR_CAF   (1 << 4)       
  68 #define DSR_MCO   (1 << 3)       
  69 #define DSR_TCO   (1 << 2)       
  70 #define DSR_NVF   (1 << 1)       
  71 #define DSR_SVF   (1 << 0)       
  72 
  73 #define DIER      0x18           
  74 #define DIER_WNIE (1 << 9)       
  75 #define DIER_WCIE (1 << 8)       
  76 #define DIER_WEIE (1 << 7)       
  77 #define DIER_CAIE (1 << 4)       
  78 #define DIER_SVIE (1 << 0)       
  79 
  80 #define DMCR      0x1c           
  81 
  82 #define DTCR      0x28           
  83 #define DTCR_MOE  (1 << 9)       
  84 #define DTCR_TOE  (1 << 8)       
  85 #define DTCR_WTE  (1 << 7)       
  86 #define DTCR_ETBE (1 << 6)       
  87 #define DTCR_ETAE (1 << 5)       
  88 #define DTCR_EBE  (1 << 4)       
  89 #define DTCR_SAIE (1 << 3)       
  90 #define DTCR_TTE  (1 << 2)       
  91 #define DTCR_CTE  (1 << 1)       
  92 #define DTCR_VTE  (1 << 0)       
  93 
  94 #define DGPR      0x3c           
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 struct imxdi_dev {
 109         struct platform_device *pdev;
 110         struct rtc_device *rtc;
 111         void __iomem *ioaddr;
 112         struct clk *clk;
 113         u32 dsr;
 114         spinlock_t irq_lock;
 115         wait_queue_head_t write_wait;
 116         struct mutex write_mutex;
 117         struct work_struct work;
 118 };
 119 
 120 
 121 
 122 
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135 
 136 
 137 
 138 
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 
 147 
 148 
 149 
 150 
 151 
 152 
 153 
 154 
 155 
 156 
 157 
 158 
 159 
 160 
 161 
 162 
 163 
 164 
 165 
 166 
 167 
 168 
 169 
 170 static void di_write_busy_wait(const struct imxdi_dev *imxdi, u32 val,
 171                                unsigned reg)
 172 {
 173         
 174         writel(val, imxdi->ioaddr + reg);
 175 
 176         
 177 
 178 
 179 
 180         usleep_range(130, 200);
 181 }
 182 
 183 static void di_report_tamper_info(struct imxdi_dev *imxdi,  u32 dsr)
 184 {
 185         u32 dtcr;
 186 
 187         dtcr = readl(imxdi->ioaddr + DTCR);
 188 
 189         dev_emerg(&imxdi->pdev->dev, "DryIce tamper event detected\n");
 190         
 191         if (dsr & DSR_VTD)
 192                 dev_emerg(&imxdi->pdev->dev, "%sVoltage Tamper Event\n",
 193                           dtcr & DTCR_VTE ? "" : "Spurious ");
 194 
 195         if (dsr & DSR_CTD)
 196                 dev_emerg(&imxdi->pdev->dev, "%s32768 Hz Clock Tamper Event\n",
 197                           dtcr & DTCR_CTE ? "" : "Spurious ");
 198 
 199         if (dsr & DSR_TTD)
 200                 dev_emerg(&imxdi->pdev->dev, "%sTemperature Tamper Event\n",
 201                           dtcr & DTCR_TTE ? "" : "Spurious ");
 202 
 203         if (dsr & DSR_SAD)
 204                 dev_emerg(&imxdi->pdev->dev,
 205                           "%sSecure Controller Alarm Event\n",
 206                           dtcr & DTCR_SAIE ? "" : "Spurious ");
 207 
 208         if (dsr & DSR_EBD)
 209                 dev_emerg(&imxdi->pdev->dev, "%sExternal Boot Tamper Event\n",
 210                           dtcr & DTCR_EBE ? "" : "Spurious ");
 211 
 212         if (dsr & DSR_ETAD)
 213                 dev_emerg(&imxdi->pdev->dev, "%sExternal Tamper A Event\n",
 214                           dtcr & DTCR_ETAE ? "" : "Spurious ");
 215 
 216         if (dsr & DSR_ETBD)
 217                 dev_emerg(&imxdi->pdev->dev, "%sExternal Tamper B Event\n",
 218                           dtcr & DTCR_ETBE ? "" : "Spurious ");
 219 
 220         if (dsr & DSR_WTD)
 221                 dev_emerg(&imxdi->pdev->dev, "%sWire-mesh Tamper Event\n",
 222                           dtcr & DTCR_WTE ? "" : "Spurious ");
 223 
 224         if (dsr & DSR_MCO)
 225                 dev_emerg(&imxdi->pdev->dev,
 226                           "%sMonotonic-counter Overflow Event\n",
 227                           dtcr & DTCR_MOE ? "" : "Spurious ");
 228 
 229         if (dsr & DSR_TCO)
 230                 dev_emerg(&imxdi->pdev->dev, "%sTimer-counter Overflow Event\n",
 231                           dtcr & DTCR_TOE ? "" : "Spurious ");
 232 }
 233 
 234 static void di_what_is_to_be_done(struct imxdi_dev *imxdi,
 235                                   const char *power_supply)
 236 {
 237         dev_emerg(&imxdi->pdev->dev, "Please cycle the %s power supply in order to get the DryIce/RTC unit working again\n",
 238                   power_supply);
 239 }
 240 
 241 static int di_handle_failure_state(struct imxdi_dev *imxdi, u32 dsr)
 242 {
 243         u32 dcr;
 244 
 245         dev_dbg(&imxdi->pdev->dev, "DSR register reports: %08X\n", dsr);
 246 
 247         
 248         di_report_tamper_info(imxdi, dsr);
 249 
 250         dcr = readl(imxdi->ioaddr + DCR);
 251 
 252         if (dcr & DCR_FSHL) {
 253                 
 254                 di_what_is_to_be_done(imxdi, "battery");
 255                 return -ENODEV;
 256         }
 257         
 258 
 259 
 260 
 261         di_what_is_to_be_done(imxdi, "main");
 262 
 263         return -ENODEV;
 264 }
 265 
 266 static int di_handle_valid_state(struct imxdi_dev *imxdi, u32 dsr)
 267 {
 268         
 269         di_write_busy_wait(imxdi, DCAMR_UNSET, DCAMR);
 270         di_write_busy_wait(imxdi, 0, DCALR);
 271 
 272         
 273         if (dsr & DSR_CAF)
 274                 di_write_busy_wait(imxdi, DSR_CAF, DSR);
 275 
 276         return 0;
 277 }
 278 
 279 static int di_handle_invalid_state(struct imxdi_dev *imxdi, u32 dsr)
 280 {
 281         u32 dcr, sec;
 282 
 283         
 284 
 285 
 286 
 287         di_write_busy_wait(imxdi, 0x00000000, DTCR);
 288         
 289         di_write_busy_wait(imxdi, DCR_TDCSL, DCR);
 290 
 291         sec = readl(imxdi->ioaddr + DTCMR);
 292         if (sec != 0)
 293                 dev_warn(&imxdi->pdev->dev,
 294                          "The security violation has happened at %u seconds\n",
 295                          sec);
 296         
 297 
 298 
 299 
 300         dcr = readl(imxdi->ioaddr + DCR);
 301         if (!(dcr & DCR_TCE)) {
 302                 if (dcr & DCR_TCHL) {
 303                         
 304                         di_what_is_to_be_done(imxdi, "battery");
 305                         return -ENODEV;
 306                 }
 307                 if (dcr & DCR_TCSL) {
 308                         di_what_is_to_be_done(imxdi, "main");
 309                         return -ENODEV;
 310                 }
 311         }
 312         
 313 
 314 
 315 
 316 
 317 
 318 
 319 
 320 
 321 
 322 
 323         
 324         di_write_busy_wait(imxdi, DSR_NVF, DSR);
 325         
 326         di_write_busy_wait(imxdi, DSR_TCO, DSR);
 327         
 328         di_write_busy_wait(imxdi, dcr | DCR_TCE, DCR);
 329         
 330         di_write_busy_wait(imxdi, sec, DTCMR);
 331 
 332         
 333         return di_handle_valid_state(imxdi, __raw_readl(imxdi->ioaddr + DSR));
 334 }
 335 
 336 static int di_handle_invalid_and_failure_state(struct imxdi_dev *imxdi, u32 dsr)
 337 {
 338         u32 dcr;
 339 
 340         
 341 
 342 
 343 
 344 
 345         if (dsr & (DSR_WTD | DSR_ETBD | DSR_ETAD | DSR_EBD | DSR_SAD |
 346                         DSR_TTD | DSR_CTD | DSR_VTD | DSR_MCO | DSR_TCO)) {
 347                 dcr = __raw_readl(imxdi->ioaddr + DCR);
 348                 if (dcr & DCR_TDCHL) {
 349                         
 350 
 351 
 352 
 353 
 354 
 355 
 356                         
 357 
 358 
 359 
 360                         di_what_is_to_be_done(imxdi, "battery");
 361                         return -ENODEV;
 362                 }
 363                 if (dcr & DCR_TDCSL) {
 364                         
 365                         di_what_is_to_be_done(imxdi, "main");
 366                         return -ENODEV;
 367                 }
 368         }
 369 
 370         
 371         di_write_busy_wait(imxdi, 0x00000000, DTCR);
 372 
 373         
 374         di_write_busy_wait(imxdi, dsr & (DSR_WTD | DSR_ETBD | DSR_ETAD |
 375                         DSR_EBD | DSR_SAD | DSR_TTD | DSR_CTD | DSR_VTD |
 376                         DSR_MCO | DSR_TCO), DSR);
 377 
 378         dsr = readl(imxdi->ioaddr + DSR);
 379         if ((dsr & ~(DSR_NVF | DSR_SVF | DSR_WBF | DSR_WNF |
 380                         DSR_WCF | DSR_WEF)) != 0)
 381                 dev_warn(&imxdi->pdev->dev,
 382                          "There are still some sources of pain in DSR: %08x!\n",
 383                          dsr & ~(DSR_NVF | DSR_SVF | DSR_WBF | DSR_WNF |
 384                                  DSR_WCF | DSR_WEF));
 385 
 386         
 387 
 388 
 389 
 390         di_write_busy_wait(imxdi, DSR_SVF, DSR);
 391 
 392         
 393         dsr = readl(imxdi->ioaddr + DSR);
 394         if (dsr & DSR_SVF) {
 395                 dev_crit(&imxdi->pdev->dev,
 396                          "Cannot clear the security violation flag. We are ending up in an endless loop!\n");
 397                 
 398                 di_what_is_to_be_done(imxdi, "battery");
 399                 return -ENODEV;
 400         }
 401 
 402         
 403 
 404 
 405 
 406         return di_handle_invalid_state(imxdi, dsr);
 407 }
 408 
 409 static int di_handle_state(struct imxdi_dev *imxdi)
 410 {
 411         int rc;
 412         u32 dsr;
 413 
 414         dsr = readl(imxdi->ioaddr + DSR);
 415 
 416         switch (dsr & (DSR_NVF | DSR_SVF)) {
 417         case DSR_NVF:
 418                 dev_warn(&imxdi->pdev->dev, "Invalid stated unit detected\n");
 419                 rc = di_handle_invalid_state(imxdi, dsr);
 420                 break;
 421         case DSR_SVF:
 422                 dev_warn(&imxdi->pdev->dev, "Failure stated unit detected\n");
 423                 rc = di_handle_failure_state(imxdi, dsr);
 424                 break;
 425         case DSR_NVF | DSR_SVF:
 426                 dev_warn(&imxdi->pdev->dev,
 427                          "Failure+Invalid stated unit detected\n");
 428                 rc = di_handle_invalid_and_failure_state(imxdi, dsr);
 429                 break;
 430         default:
 431                 dev_notice(&imxdi->pdev->dev, "Unlocked unit detected\n");
 432                 rc = di_handle_valid_state(imxdi, dsr);
 433         }
 434 
 435         return rc;
 436 }
 437 
 438 
 439 
 440 
 441 static void di_int_enable(struct imxdi_dev *imxdi, u32 intr)
 442 {
 443         unsigned long flags;
 444 
 445         spin_lock_irqsave(&imxdi->irq_lock, flags);
 446         writel(readl(imxdi->ioaddr + DIER) | intr,
 447                imxdi->ioaddr + DIER);
 448         spin_unlock_irqrestore(&imxdi->irq_lock, flags);
 449 }
 450 
 451 
 452 
 453 
 454 static void di_int_disable(struct imxdi_dev *imxdi, u32 intr)
 455 {
 456         unsigned long flags;
 457 
 458         spin_lock_irqsave(&imxdi->irq_lock, flags);
 459         writel(readl(imxdi->ioaddr + DIER) & ~intr,
 460                imxdi->ioaddr + DIER);
 461         spin_unlock_irqrestore(&imxdi->irq_lock, flags);
 462 }
 463 
 464 
 465 
 466 
 467 
 468 
 469 
 470 
 471 static void clear_write_error(struct imxdi_dev *imxdi)
 472 {
 473         int cnt;
 474 
 475         dev_warn(&imxdi->pdev->dev, "WARNING: Register write error!\n");
 476 
 477         
 478         writel(DSR_WEF, imxdi->ioaddr + DSR);
 479 
 480         
 481         for (cnt = 0; cnt < 1000; cnt++) {
 482                 if ((readl(imxdi->ioaddr + DSR) & DSR_WEF) == 0)
 483                         return;
 484                 udelay(10);
 485         }
 486         dev_err(&imxdi->pdev->dev,
 487                         "ERROR: Cannot clear write-error flag!\n");
 488 }
 489 
 490 
 491 
 492 
 493 
 494 
 495 
 496 static int di_write_wait(struct imxdi_dev *imxdi, u32 val, int reg)
 497 {
 498         int ret;
 499         int rc = 0;
 500 
 501         
 502         mutex_lock(&imxdi->write_mutex);
 503 
 504         
 505         di_int_enable(imxdi, DIER_WCIE);
 506 
 507         imxdi->dsr = 0;
 508 
 509         
 510         writel(val, imxdi->ioaddr + reg);
 511 
 512         
 513         ret = wait_event_interruptible_timeout(imxdi->write_wait,
 514                         imxdi->dsr & (DSR_WCF | DSR_WEF), msecs_to_jiffies(1));
 515         if (ret < 0) {
 516                 rc = ret;
 517                 goto out;
 518         } else if (ret == 0) {
 519                 dev_warn(&imxdi->pdev->dev,
 520                                 "Write-wait timeout "
 521                                 "val = 0x%08x reg = 0x%08x\n", val, reg);
 522         }
 523 
 524         
 525         if (imxdi->dsr & DSR_WEF) {
 526                 clear_write_error(imxdi);
 527                 rc = -EIO;
 528         }
 529 
 530 out:
 531         mutex_unlock(&imxdi->write_mutex);
 532 
 533         return rc;
 534 }
 535 
 536 
 537 
 538 
 539 static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm)
 540 {
 541         struct imxdi_dev *imxdi = dev_get_drvdata(dev);
 542         unsigned long now;
 543 
 544         now = readl(imxdi->ioaddr + DTCMR);
 545         rtc_time64_to_tm(now, tm);
 546 
 547         return 0;
 548 }
 549 
 550 
 551 
 552 
 553 
 554 static int dryice_rtc_set_time(struct device *dev, struct rtc_time *tm)
 555 {
 556         struct imxdi_dev *imxdi = dev_get_drvdata(dev);
 557         u32 dcr, dsr;
 558         int rc;
 559 
 560         dcr = readl(imxdi->ioaddr + DCR);
 561         dsr = readl(imxdi->ioaddr + DSR);
 562 
 563         if (!(dcr & DCR_TCE) || (dsr & DSR_SVF)) {
 564                 if (dcr & DCR_TCHL) {
 565                         
 566                         di_what_is_to_be_done(imxdi, "battery");
 567                         return -EPERM;
 568                 }
 569                 if ((dcr & DCR_TCSL) || (dsr & DSR_SVF)) {
 570                         
 571                         di_what_is_to_be_done(imxdi, "main");
 572                         return -EPERM;
 573                 }
 574         }
 575 
 576         
 577         rc = di_write_wait(imxdi, 0, DTCLR);
 578         if (rc != 0)
 579                 return rc;
 580 
 581         rc = di_write_wait(imxdi, rtc_tm_to_time64(tm), DTCMR);
 582         if (rc != 0)
 583                 return rc;
 584 
 585         return di_write_wait(imxdi, readl(imxdi->ioaddr + DCR) | DCR_TCE, DCR);
 586 }
 587 
 588 static int dryice_rtc_alarm_irq_enable(struct device *dev,
 589                 unsigned int enabled)
 590 {
 591         struct imxdi_dev *imxdi = dev_get_drvdata(dev);
 592 
 593         if (enabled)
 594                 di_int_enable(imxdi, DIER_CAIE);
 595         else
 596                 di_int_disable(imxdi, DIER_CAIE);
 597 
 598         return 0;
 599 }
 600 
 601 
 602 
 603 
 604 
 605 static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 606 {
 607         struct imxdi_dev *imxdi = dev_get_drvdata(dev);
 608         u32 dcamr;
 609 
 610         dcamr = readl(imxdi->ioaddr + DCAMR);
 611         rtc_time64_to_tm(dcamr, &alarm->time);
 612 
 613         
 614         alarm->enabled = (readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0;
 615 
 616         
 617         mutex_lock(&imxdi->write_mutex);
 618 
 619         
 620         alarm->pending = (readl(imxdi->ioaddr + DSR) & DSR_CAF) != 0;
 621 
 622         mutex_unlock(&imxdi->write_mutex);
 623 
 624         return 0;
 625 }
 626 
 627 
 628 
 629 
 630 static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 631 {
 632         struct imxdi_dev *imxdi = dev_get_drvdata(dev);
 633         int rc;
 634 
 635         
 636         rc = di_write_wait(imxdi, rtc_tm_to_time64(&alarm->time), DCAMR);
 637         if (rc)
 638                 return rc;
 639 
 640         if (alarm->enabled)
 641                 di_int_enable(imxdi, DIER_CAIE);  
 642         else
 643                 di_int_disable(imxdi, DIER_CAIE); 
 644 
 645         return 0;
 646 }
 647 
 648 static const struct rtc_class_ops dryice_rtc_ops = {
 649         .read_time              = dryice_rtc_read_time,
 650         .set_time               = dryice_rtc_set_time,
 651         .alarm_irq_enable       = dryice_rtc_alarm_irq_enable,
 652         .read_alarm             = dryice_rtc_read_alarm,
 653         .set_alarm              = dryice_rtc_set_alarm,
 654 };
 655 
 656 
 657 
 658 
 659 static irqreturn_t dryice_irq(int irq, void *dev_id)
 660 {
 661         struct imxdi_dev *imxdi = dev_id;
 662         u32 dsr, dier;
 663         irqreturn_t rc = IRQ_NONE;
 664 
 665         dier = readl(imxdi->ioaddr + DIER);
 666         dsr = readl(imxdi->ioaddr + DSR);
 667 
 668         
 669         if (dier & DIER_SVIE) {
 670                 if (dsr & DSR_SVF) {
 671                         
 672 
 673 
 674 
 675 
 676 
 677 
 678 
 679                         di_int_disable(imxdi, DIER_SVIE);
 680                         
 681                         di_report_tamper_info(imxdi, dsr);
 682                         rc = IRQ_HANDLED;
 683                 }
 684         }
 685 
 686         
 687         if (dier & DIER_WCIE) {
 688                 
 689 
 690 
 691                 if (list_empty_careful(&imxdi->write_wait.head))
 692                         return rc;
 693 
 694                 
 695                 if (dsr & (DSR_WCF | DSR_WEF)) {
 696                         
 697                         di_int_disable(imxdi, DIER_WCIE);
 698 
 699                         
 700                         imxdi->dsr |= dsr;
 701 
 702                         wake_up_interruptible(&imxdi->write_wait);
 703                         rc = IRQ_HANDLED;
 704                 }
 705         }
 706 
 707         
 708         if (dier & DIER_CAIE) {
 709                 
 710                 if (dsr & DSR_CAF) {
 711                         
 712                         di_int_disable(imxdi, DIER_CAIE);
 713 
 714                         
 715                         schedule_work(&imxdi->work);
 716                         rc = IRQ_HANDLED;
 717                 }
 718         }
 719         return rc;
 720 }
 721 
 722 
 723 
 724 
 725 
 726 static void dryice_work(struct work_struct *work)
 727 {
 728         struct imxdi_dev *imxdi = container_of(work,
 729                         struct imxdi_dev, work);
 730 
 731         
 732         di_write_wait(imxdi, DSR_CAF, DSR);
 733 
 734         
 735         rtc_update_irq(imxdi->rtc, 1, RTC_AF | RTC_IRQF);
 736 }
 737 
 738 
 739 
 740 
 741 static int __init dryice_rtc_probe(struct platform_device *pdev)
 742 {
 743         struct imxdi_dev *imxdi;
 744         int norm_irq, sec_irq;
 745         int rc;
 746 
 747         imxdi = devm_kzalloc(&pdev->dev, sizeof(*imxdi), GFP_KERNEL);
 748         if (!imxdi)
 749                 return -ENOMEM;
 750 
 751         imxdi->pdev = pdev;
 752 
 753         imxdi->ioaddr = devm_platform_ioremap_resource(pdev, 0);
 754         if (IS_ERR(imxdi->ioaddr))
 755                 return PTR_ERR(imxdi->ioaddr);
 756 
 757         spin_lock_init(&imxdi->irq_lock);
 758 
 759         norm_irq = platform_get_irq(pdev, 0);
 760         if (norm_irq < 0)
 761                 return norm_irq;
 762 
 763         
 764 
 765 
 766         sec_irq = platform_get_irq(pdev, 1);
 767         if (sec_irq <= 0)
 768                 sec_irq = IRQ_NOTCONNECTED;
 769 
 770         init_waitqueue_head(&imxdi->write_wait);
 771 
 772         INIT_WORK(&imxdi->work, dryice_work);
 773 
 774         mutex_init(&imxdi->write_mutex);
 775 
 776         imxdi->rtc = devm_rtc_allocate_device(&pdev->dev);
 777         if (IS_ERR(imxdi->rtc))
 778                 return PTR_ERR(imxdi->rtc);
 779 
 780         imxdi->clk = devm_clk_get(&pdev->dev, NULL);
 781         if (IS_ERR(imxdi->clk))
 782                 return PTR_ERR(imxdi->clk);
 783         rc = clk_prepare_enable(imxdi->clk);
 784         if (rc)
 785                 return rc;
 786 
 787         
 788 
 789 
 790 
 791         
 792         writel(0, imxdi->ioaddr + DIER);
 793 
 794         rc = di_handle_state(imxdi);
 795         if (rc != 0)
 796                 goto err;
 797 
 798         rc = devm_request_irq(&pdev->dev, norm_irq, dryice_irq,
 799                               IRQF_SHARED, pdev->name, imxdi);
 800         if (rc) {
 801                 dev_warn(&pdev->dev, "interrupt not available.\n");
 802                 goto err;
 803         }
 804 
 805         rc = devm_request_irq(&pdev->dev, sec_irq, dryice_irq,
 806                               IRQF_SHARED, pdev->name, imxdi);
 807         if (rc) {
 808                 dev_warn(&pdev->dev, "security violation interrupt not available.\n");
 809                 
 810         }
 811 
 812         platform_set_drvdata(pdev, imxdi);
 813 
 814         imxdi->rtc->ops = &dryice_rtc_ops;
 815         imxdi->rtc->range_max = U32_MAX;
 816 
 817         rc = rtc_register_device(imxdi->rtc);
 818         if (rc)
 819                 goto err;
 820 
 821         return 0;
 822 
 823 err:
 824         clk_disable_unprepare(imxdi->clk);
 825 
 826         return rc;
 827 }
 828 
 829 static int __exit dryice_rtc_remove(struct platform_device *pdev)
 830 {
 831         struct imxdi_dev *imxdi = platform_get_drvdata(pdev);
 832 
 833         flush_work(&imxdi->work);
 834 
 835         
 836         writel(0, imxdi->ioaddr + DIER);
 837 
 838         clk_disable_unprepare(imxdi->clk);
 839 
 840         return 0;
 841 }
 842 
 843 #ifdef CONFIG_OF
 844 static const struct of_device_id dryice_dt_ids[] = {
 845         { .compatible = "fsl,imx25-rtc" },
 846         {  }
 847 };
 848 
 849 MODULE_DEVICE_TABLE(of, dryice_dt_ids);
 850 #endif
 851 
 852 static struct platform_driver dryice_rtc_driver = {
 853         .driver = {
 854                    .name = "imxdi_rtc",
 855                    .of_match_table = of_match_ptr(dryice_dt_ids),
 856                    },
 857         .remove = __exit_p(dryice_rtc_remove),
 858 };
 859 
 860 module_platform_driver_probe(dryice_rtc_driver, dryice_rtc_probe);
 861 
 862 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 863 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
 864 MODULE_DESCRIPTION("IMX DryIce Realtime Clock Driver (RTC)");
 865 MODULE_LICENSE("GPL");