diff options
author | Juergen Borleis <jbe@pengutronix.de> | 2015-04-27 09:59:50 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2015-06-19 14:03:21 -0400 |
commit | a7c535e3a8e50e625750d2aa0ed4f84591ca7bfa (patch) | |
tree | 93789de830bbb2c6dd0d7eee6fcee9d1d02dcf7c /drivers/rtc | |
parent | c7e9bbe022c7bee57d9e14b42a7c3732da8db558 (diff) |
rtc: imxdi: monitor a security violation at runtime
Maybe the unit enters the hardware related state at runtime and not at
system boot time (after a power cycle).
Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
Signed-off-by: Robert Schwebel <rsc@pengutronix.de>
[rsc: got NDA clearance from Freescale]
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-imxdi.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 3d7f0390170e..a08da4a353db 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
@@ -665,6 +665,25 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) | |||
665 | irqreturn_t rc = IRQ_NONE; | 665 | irqreturn_t rc = IRQ_NONE; |
666 | 666 | ||
667 | dier = readl(imxdi->ioaddr + DIER); | 667 | dier = readl(imxdi->ioaddr + DIER); |
668 | dsr = readl(imxdi->ioaddr + DSR); | ||
669 | |||
670 | /* handle the security violation event */ | ||
671 | if (dier & DIER_SVIE) { | ||
672 | if (dsr & DSR_SVF) { | ||
673 | /* | ||
674 | * Disable the interrupt when this kind of event has | ||
675 | * happened. | ||
676 | * There cannot be more than one event of this type, | ||
677 | * because it needs a complex state change | ||
678 | * including a main power cycle to get again out of | ||
679 | * this state. | ||
680 | */ | ||
681 | di_int_disable(imxdi, DIER_SVIE); | ||
682 | /* report the violation */ | ||
683 | di_report_tamper_info(imxdi, dsr); | ||
684 | rc = IRQ_HANDLED; | ||
685 | } | ||
686 | } | ||
668 | 687 | ||
669 | /* handle write complete and write error cases */ | 688 | /* handle write complete and write error cases */ |
670 | if (dier & DIER_WCIE) { | 689 | if (dier & DIER_WCIE) { |
@@ -675,7 +694,6 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) | |||
675 | return rc; | 694 | return rc; |
676 | 695 | ||
677 | /* DSR_WCF clears itself on DSR read */ | 696 | /* DSR_WCF clears itself on DSR read */ |
678 | dsr = readl(imxdi->ioaddr + DSR); | ||
679 | if (dsr & (DSR_WCF | DSR_WEF)) { | 697 | if (dsr & (DSR_WCF | DSR_WEF)) { |
680 | /* mask the interrupt */ | 698 | /* mask the interrupt */ |
681 | di_int_disable(imxdi, DIER_WCIE); | 699 | di_int_disable(imxdi, DIER_WCIE); |
@@ -691,7 +709,6 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) | |||
691 | /* handle the alarm case */ | 709 | /* handle the alarm case */ |
692 | if (dier & DIER_CAIE) { | 710 | if (dier & DIER_CAIE) { |
693 | /* DSR_WCF clears itself on DSR read */ | 711 | /* DSR_WCF clears itself on DSR read */ |
694 | dsr = readl(imxdi->ioaddr + DSR); | ||
695 | if (dsr & DSR_CAF) { | 712 | if (dsr & DSR_CAF) { |
696 | /* mask the interrupt */ | 713 | /* mask the interrupt */ |
697 | di_int_disable(imxdi, DIER_CAIE); | 714 | di_int_disable(imxdi, DIER_CAIE); |