1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#ifndef _LINUX_FIQ_C_ISR_H
#define _LINUX_FIQ_C_ISR_H
#include <mach/regs-irq.h>
#include <linux/platform_device.h>
extern unsigned long _fiq_count_fiqs;
extern u32 _fiq_ack_mask;
extern int _fiq_timer_index;
extern u16 _fiq_timer_divisor;
/* platform data */
struct sc32440_fiq_platform_data {
/*
* give an opportunity to use us as parent for
* devices that depend on us
*/
void (*attach_child_devices)(struct device *parent_device);
};
/* 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__ (\
/* 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 */
|