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