diff options
-rw-r--r-- | arch/arm/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 13 | ||||
-rw-r--r-- | include/asm-arm/irqflags.h | 132 | ||||
-rw-r--r-- | include/asm-arm/system.h | 125 |
4 files changed, 150 insertions, 124 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f81a62380ad..d9376f048ed 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -51,6 +51,10 @@ config GENERIC_HARDIRQS bool default y +config TRACE_IRQFLAGS_SUPPORT + bool + default y + config HARDIRQS_SW_RESEND bool default y diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index de4e3313790..bd623b73445 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -191,6 +191,9 @@ __dabt_svc: __irq_svc: svc_entry +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif #ifdef CONFIG_PREEMPT get_thread_info tsk ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -211,6 +214,10 @@ preempt_return: #endif ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr_cxsf, r0 +#ifdef CONFIG_TRACE_IRQFLAGS + tst r0, #PSR_I_BIT + bleq trace_hardirqs_on +#endif ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .ltorg @@ -398,6 +405,9 @@ __dabt_usr: __irq_usr: usr_entry +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif get_thread_info tsk #ifdef CONFIG_PREEMPT ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -412,6 +422,9 @@ __irq_usr: teq r0, r7 strne r0, [r0, -r0] #endif +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_on +#endif mov why, #0 b ret_to_user diff --git a/include/asm-arm/irqflags.h b/include/asm-arm/irqflags.h new file mode 100644 index 00000000000..6d09974e664 --- /dev/null +++ b/include/asm-arm/irqflags.h @@ -0,0 +1,132 @@ +#ifndef __ASM_ARM_IRQFLAGS_H +#define __ASM_ARM_IRQFLAGS_H + +#ifdef __KERNEL__ + +#include <asm/ptrace.h> + +/* + * CPU interrupt mask handling. + */ +#if __LINUX_ARM_ARCH__ >= 6 + +#define raw_local_irq_save(x) \ + ({ \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_save\n" \ + "cpsid i" \ + : "=r" (x) : : "memory", "cc"); \ + }) + +#define raw_local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc") +#define raw_local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc") +#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") +#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") + +#else + +/* + * Save the current interrupt enable state & disable IRQs + */ +#define raw_local_irq_save(x) \ + ({ \ + unsigned long temp; \ + (void) (&temp == &x); \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_save\n" \ +" orr %1, %0, #128\n" \ +" msr cpsr_c, %1" \ + : "=r" (x), "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Enable IRQs + */ +#define raw_local_irq_enable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_enable\n" \ +" bic %0, %0, #128\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Disable IRQs + */ +#define raw_local_irq_disable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_disable\n" \ +" orr %0, %0, #128\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Enable FIQs + */ +#define local_fiq_enable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ stf\n" \ +" bic %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Disable FIQs + */ +#define local_fiq_disable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ clf\n" \ +" orr %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +#endif + +/* + * Save the current interrupt enable state. + */ +#define raw_local_save_flags(x) \ + ({ \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_save_flags" \ + : "=r" (x) : : "memory", "cc"); \ + }) + +/* + * restore saved IRQ & FIQ state + */ +#define raw_local_irq_restore(x) \ + __asm__ __volatile__( \ + "msr cpsr_c, %0 @ local_irq_restore\n" \ + : \ + : "r" (x) \ + : "memory", "cc") + +#define raw_irqs_disabled_flags(flags) \ +({ \ + (int)((flags) & PSR_I_BIT); \ +}) + +#endif +#endif diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 0947cbf9b69..174ff52661b 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -207,130 +207,7 @@ static inline void sched_cacheflush(void) { } -/* - * CPU interrupt mask handling. - */ -#if __LINUX_ARM_ARCH__ >= 6 - -#define local_irq_save(x) \ - ({ \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ - "cpsid i" \ - : "=r" (x) : : "memory", "cc"); \ - }) - -#define local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc") -#define local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc") -#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") -#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") - -#else - -/* - * Save the current interrupt enable state & disable IRQs - */ -#define local_irq_save(x) \ - ({ \ - unsigned long temp; \ - (void) (&temp == &x); \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ -" orr %1, %0, #128\n" \ -" msr cpsr_c, %1" \ - : "=r" (x), "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Enable IRQs - */ -#define local_irq_enable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_enable\n" \ -" bic %0, %0, #128\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Disable IRQs - */ -#define local_irq_disable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_disable\n" \ -" orr %0, %0, #128\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Enable FIQs - */ -#define local_fiq_enable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ stf\n" \ -" bic %0, %0, #64\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Disable FIQs - */ -#define local_fiq_disable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ clf\n" \ -" orr %0, %0, #64\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -#endif - -/* - * Save the current interrupt enable state. - */ -#define local_save_flags(x) \ - ({ \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_save_flags" \ - : "=r" (x) : : "memory", "cc"); \ - }) - -/* - * restore saved IRQ & FIQ state - */ -#define local_irq_restore(x) \ - __asm__ __volatile__( \ - "msr cpsr_c, %0 @ local_irq_restore\n" \ - : \ - : "r" (x) \ - : "memory", "cc") - -#define irqs_disabled() \ -({ \ - unsigned long flags; \ - local_save_flags(flags); \ - (int)(flags & PSR_I_BIT); \ -}) +#include <linux/irqflags.h> #ifdef CONFIG_SMP |