Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / cmnos / intr / src / cmnos_intr.c
1
2 #include "sys_cfg.h"
3
4 #if SYSTEM_MODULE_INTR
5
6 #include "athos_api.h"
7 #include "regdump.h"
8
9 /*
10  * Interrupt Service Routine information, one for each interrupt that
11  * is known to the CPU.  A single CPU-level interrupt is sometimes used
12  * for multiple interrupts.  For example, all GPIO interrupts share a
13  * single "interrupt number" and all low frequency timers share a single
14  * interrupt number.
15  *
16  * Index into this table is a platform-dependent interrupt A_INUM_* number.
17  */
18 LOCAL struct {
19     A_isr_t                isr;         /* function to call */
20     void                  *isr_arg;     /* argument to pass */
21 } cmnos_isr_info[NUM_DIRECT_INTR];
22
23
24
25 //int cmnos_invalid_isr_count; /* Track these for debug purposes */
26 LOCAL uint32_t cmnos_enabled_interrupts = 0; /* Shadows enabled interrupts */
27
28
29 LOCAL uint32_t cmnos_intr_dummy(void *pParm)
30 {
31     // dummy function in case any intr coming calling the null and crash
32 }
33
34 /*! - cmnos_intr_init
35  *
36  *  initialize all interrupt to diable, and setup all callback to dummy function
37  *  
38  *  p.s these are only level2 interrupt
39  */
40 LOCAL void
41 cmnos_intr_init(void)
42 {
43     uint32_t i=0;
44     
45     // disable all at init
46     cmnos_enabled_interrupts = 0;
47
48     // install the dummy function
49     for(i=0; i<NUM_DIRECT_INTR; i++)
50         cmnos_isr_info[i].isr = cmnos_intr_dummy;
51
52     // set intrenable to disable all
53     A_INTR_SET_INTRENABLE(cmnos_enabled_interrupts);
54
55 }
56
57
58 LOCAL void
59 cmnos_intr_mask_inum(uint32_t inum)
60 {
61     A_old_intr_t old_intr;
62     unsigned oldval;
63     int mask = 1 << inum;
64
65     A_INTR_DISABLE(&old_intr);
66     oldval = A_INTR_GET_INTRENABLE();
67     cmnos_enabled_interrupts &= ~mask;
68     oldval &= ~mask;
69     A_INTR_SET_INTRENABLE(oldval);
70     A_INTR_RESTORE(old_intr);
71 }
72
73 LOCAL void
74 cmnos_intr_unmask_inum(uint32_t inum)
75 {
76     A_old_intr_t old_intr;
77     unsigned oldval;
78     int unmask = 1 << inum;
79
80     A_INTR_DISABLE(&old_intr);
81     oldval = A_INTR_GET_INTRENABLE();
82     cmnos_enabled_interrupts |= unmask;
83 //    if (!pending_dsr) {
84         oldval |= unmask;
85 //    }
86     A_INTR_SET_INTRENABLE(oldval);
87     A_INTR_RESTORE(old_intr);
88 }
89
90
91 LOCAL void
92 cmnos_intr_attach_isr(uint32_t inum, A_isr_t isr, void *arg)
93 {
94     A_old_intr_t old_intr;
95
96     A_ASSERT(inum < NUM_DIRECT_INTR);
97     A_ASSERT(isr != NULL);
98
99      A_INTR_DISABLE(&old_intr);
100
101     cmnos_isr_info[inum].isr = isr;
102     cmnos_isr_info[inum].isr_arg = arg;
103
104     A_INTR_RESTORE(old_intr);
105 }
106
107 /*
108  * Invoke the ISR corresponding to an interrupt number.
109  * Note that we expect interrupts for the given interrupt
110  * number to be blocked when this function is called.  In
111  * fact, current ISRs assume that ALL non-fatal interrupts
112  * are blocked, and this allows the ISRs to avoid excessive
113  * calls to A_INTR_DISABLE/RESTORE which would otherwise be
114  * needed around calls to A_INTR_SET_INTRENABLE and such.
115  */
116 LOCAL uint32_t
117 cmnos_intr_invoke_isr(uint32_t inum)
118 {
119     A_ASSERT(inum < NUM_DIRECT_INTR);
120     A_ASSERT(cmnos_isr_info[inum].isr != NULL);
121
122 //    A_PRINTF("cmnos_intr_invoke_isr %d\n", inum);
123     
124     return cmnos_isr_info[inum].isr(cmnos_isr_info[inum].isr_arg);
125 }
126
127 /*
128  * NB: Whenever an "inum" is passed to an intr API, it is an A_INUM_*.
129  */
130 void
131 cmnos_intr_module_install(struct intr_api *tbl)
132 {
133     tbl->_intr_init                     = cmnos_intr_init;
134     tbl->_intr_invoke_isr               = cmnos_intr_invoke_isr;
135         tbl->_intr_attach_isr               = cmnos_intr_attach_isr;
136     tbl->_intr_mask_inum                = cmnos_intr_mask_inum;
137     tbl->_intr_unmask_inum              = cmnos_intr_unmask_inum;
138
139     /*
140      * Note: These are all supplied elsewhere with platform-specific functions:
141      *   tbl->_get_intrenable
142      *   tbl->_set_intrenable
143      *   tbl->_get_intrpending
144      *   tbl->_unblock_all_intrlvl
145      *   tbl->_intr_disable
146      *   tbl->_intr_restore
147      */
148 }
149 #endif /* SYSTEM_MODULE_INTR */
150