aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/assembler.h
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2009-08-13 20:38:17 +0200
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2009-08-13 20:34:37 +0200
commit0d928b0b616d1c5c5fe76019a87cba171ca91633 (patch)
treedb71283925be4df3ea3cf66f9a3eab5f4f349a06 /arch/arm/include/asm/assembler.h
parent181f817eaaca4c1f8a9c265d339d2b96de8b245d (diff)
downloadkernel_samsung_smdk4412-0d928b0b616d1c5c5fe76019a87cba171ca91633.zip
kernel_samsung_smdk4412-0d928b0b616d1c5c5fe76019a87cba171ca91633.tar.gz
kernel_samsung_smdk4412-0d928b0b616d1c5c5fe76019a87cba171ca91633.tar.bz2
Complete irq tracing support for ARM
Before this patch enabling and disabling irqs in assembler code and by the hardware wasn't tracked completly. I had to transpose two instructions in arch/arm/lib/bitops.h because restore_irqs doesn't preserve the flags with CONFIG_TRACE_IRQFLAGS=y Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Cc: Russell King <linux@arm.linux.org.uk> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@redhat.com> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Diffstat (limited to 'arch/arm/include/asm/assembler.h')
-rw-r--r--arch/arm/include/asm/assembler.h49
1 files changed, 44 insertions, 5 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 15f8a09..44912cd 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -74,23 +74,56 @@
* Enable and disable interrupts
*/
#if __LINUX_ARM_ARCH__ >= 6
- .macro disable_irq
+ .macro disable_irq_notrace
cpsid i
.endm
- .macro enable_irq
+ .macro enable_irq_notrace
cpsie i
.endm
#else
- .macro disable_irq
+ .macro disable_irq_notrace
msr cpsr_c, #PSR_I_BIT | SVC_MODE
.endm
- .macro enable_irq
+ .macro enable_irq_notrace
msr cpsr_c, #SVC_MODE
.endm
#endif
+ .macro asm_trace_hardirqs_off
+#if defined(CONFIG_TRACE_IRQFLAGS)
+ stmdb sp!, {r0-r3, ip, lr}
+ bl trace_hardirqs_off
+ ldmia sp!, {r0-r3, ip, lr}
+#endif
+ .endm
+
+ .macro asm_trace_hardirqs_on_cond, cond
+#if defined(CONFIG_TRACE_IRQFLAGS)
+ /*
+ * actually the registers should be pushed and pop'd conditionally, but
+ * after bl the flags are certainly clobbered
+ */
+ stmdb sp!, {r0-r3, ip, lr}
+ bl\cond trace_hardirqs_on
+ ldmia sp!, {r0-r3, ip, lr}
+#endif
+ .endm
+
+ .macro asm_trace_hardirqs_on
+ asm_trace_hardirqs_on_cond al
+ .endm
+
+ .macro disable_irq
+ disable_irq_notrace
+ asm_trace_hardirqs_off
+ .endm
+
+ .macro enable_irq
+ asm_trace_hardirqs_on
+ enable_irq_notrace
+ .endm
/*
* Save the current IRQ state and disable IRQs. Note that this macro
* assumes FIQs are enabled, and that the processor is in SVC mode.
@@ -104,10 +137,16 @@
* Restore interrupt state previously stored in a register. We don't
* guarantee that this will preserve the flags.
*/
- .macro restore_irqs, oldcpsr
+ .macro restore_irqs_notrace, oldcpsr
msr cpsr_c, \oldcpsr
.endm
+ .macro restore_irqs, oldcpsr
+ tst \oldcpsr, #PSR_I_BIT
+ asm_trace_hardirqs_on_cond eq
+ restore_irqs_notrace \oldcpsr
+ .endm
+
#define USER(x...) \
9999: x; \
.section __ex_table,"a"; \