aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-s3c2440/fiq_c_isr.h
diff options
context:
space:
mode:
authormokopatches <mokopatches@openmoko.org>2008-11-19 17:03:18 +0000
committerwarmcat <andy@warmcat.com>2008-11-19 17:03:18 +0000
commit8fd8547b742a608695823e38ca7cfc531d50f341 (patch)
tree05961aeb23ba98de4bb8d42b4552147be3f3060a /arch/arm/mach-s3c2440/fiq_c_isr.h
parentce82f1353a5b9e1466369106ba7be5eca86c5e49 (diff)
introduce-fiq-basis.patch
Adds a C-based FIQ ISR which is very convenient (and unusual -- normally you have to do FIQ ISR in assembler only). Based on my article: http://warmcat.com/_wp/2007/09/17/at91rm9200-fiq-faq-and-simple-example-code-patch/ Implemented as a platform device and driver. Suspend / resume is tested and works. Signed-off-by: Andy Green <andy@warmcat.com>
Diffstat (limited to 'arch/arm/mach-s3c2440/fiq_c_isr.h')
-rw-r--r--arch/arm/mach-s3c2440/fiq_c_isr.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.h b/arch/arm/mach-s3c2440/fiq_c_isr.h
new file mode 100644
index 00000000000..f08740ee8d3
--- /dev/null
+++ b/arch/arm/mach-s3c2440/fiq_c_isr.h
@@ -0,0 +1,64 @@
+#ifndef _LINUX_FIQ_C_ISR_H
+#define _LINUX_FIQ_C_ISR_H
+
+#include <asm/arch-s3c2410/regs-irq.h>
+
+extern unsigned long _fiq_count_fiqs;
+extern u32 _fiq_ack_mask;
+
+/* This CANNOT be implemented in a module -- it has to be used in code
+ * included in the monolithic kernel
+ */
+
+#define FIQ_HANDLER_START() \
+void __attribute__ ((naked)) s3c2440_fiq_isr(void) \
+{\
+ /*\
+ * you can declare local vars here, take care to set the frame size\
+ * below accordingly if there are more than a few dozen bytes of them\
+ */\
+
+/* stick your locals here :-)
+ * Do NOT initialize them here! define them and initialize them after
+ * FIQ_HANDLER_ENTRY() is done.
+ */
+
+#define FIQ_HANDLER_ENTRY(LOCALS, FRAME) \
+ const int _FIQ_FRAME_SIZE = FRAME; \
+ /* entry takes care to store registers we will be treading on here */\
+ asm __volatile__ (\
+ "mov ip, sp ;"\
+ /* stash FIQ and r0-r8 normal regs */\
+ "stmdb sp!, {r0-r12, lr};"\
+ /* allow SP to get some space */\
+ "sub sp, sp, %1 ;"\
+ /* !! THIS SETS THE FRAME, adjust to > sizeof locals */\
+ "sub fp, sp, %0 ;"\
+ :\
+ : "rI" (LOCALS), "rI" (FRAME)\
+ :"r9"\
+ );
+
+/* stick your ISR code here and then end with... */
+
+#define FIQ_HANDLER_END() \
+ _fiq_count_fiqs++;\
+ __raw_writel(_fiq_ack_mask, S3C2410_SRCPND);\
+\
+ /* exit back to normal mode restoring everything */\
+ asm __volatile__ (\
+ /* pop our allocation */\
+ "add sp, sp, %0 ;"\
+ /* return FIQ regs back to pristine state\
+ * and get normal regs back\
+ */\
+ "ldmia sp!, {r0-r12, lr};"\
+\
+ /* return */\
+ "subs pc, lr, #4;"\
+ : \
+ : "rI" (_FIQ_FRAME_SIZE) \
+ );\
+}
+
+#endif /* _LINUX_FIQ_C_ISR_H */