summaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/entry-arcv2.S
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2016-09-23 23:09:30 +0200
committerVineet Gupta <vgupta@synopsys.com>2016-12-14 18:23:45 +0100
commit78833e79d516901413d6e9278cbebf6116d62c78 (patch)
treedafd32200cca4b96f8372868f4f9ea3a50416299 /arch/arc/kernel/entry-arcv2.S
parentARC: ARCompact entry: elide re-reading ECR in ProtV handler (diff)
downloadlinux-78833e79d516901413d6e9278cbebf6116d62c78.tar.xz
linux-78833e79d516901413d6e9278cbebf6116d62c78.zip
ARCv2: entry: document intr disable in hard isr
And while at it - use the proper assembler macro which includes the optional irq tracing already - de-uglify'ing the code a bit Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel/entry-arcv2.S')
-rw-r--r--arch/arc/kernel/entry-arcv2.S24
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S
index 7a1c124ff021..0b6388a5f0b8 100644
--- a/arch/arc/kernel/entry-arcv2.S
+++ b/arch/arc/kernel/entry-arcv2.S
@@ -67,12 +67,23 @@ ENTRY(handle_interrupt)
INTERRUPT_PROLOGUE irq
- clri ; To make status32.IE agree with CPU internal state
-
-#ifdef CONFIG_TRACE_IRQFLAGS
- TRACE_ASM_IRQ_DISABLE
-#endif
-
+ # irq control APIs local_irq_save/restore/disable/enable fiddle with
+ # global interrupt enable bits in STATUS32 (.IE for 1 prio, .E[] for 2 prio)
+ # However a taken interrupt doesn't clear these bits. Thus irqs_disabled()
+ # query in hard ISR path would return false (since .IE is set) which would
+ # trips genirq interrupt handling asserts.
+ #
+ # So do a "soft" disable of interrutps here.
+ #
+ # Note this disable is only for consistent book-keeping as further interrupts
+ # will be disabled anyways even w/o this. Hardware tracks active interrupts
+ # seperately in AUX_IRQ_ACTIVE.active and will not take new interrupts
+ # unless this one returns (or higher prio becomes pending in 2-prio scheme)
+
+ IRQ_DISABLE
+
+ ; icause is banked: one per priority level
+ ; so a higher prio interrupt taken here won't clobber prev prio icause
lr r0, [ICAUSE]
mov blink, ret_from_exception
@@ -171,6 +182,7 @@ END(EV_TLBProtV)
; All 2 entry points to here already disable interrupts
.Lrestore_regs:
+restore_regs:
# Interrpts are actually disabled from this point on, but will get
# reenabled after we return from interrupt/exception.