Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / magpie_1_1 / sboot / cmnos / intr / src / cmnos_intr.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 #include "sys_cfg.h"
36
37 #if SYSTEM_MODULE_INTR
38
39 #include "athos_api.h"
40 #include "regdump.h"
41
42 /*
43  * Interrupt Service Routine information, one for each interrupt that
44  * is known to the CPU.  A single CPU-level interrupt is sometimes used
45  * for multiple interrupts.  For example, all GPIO interrupts share a
46  * single "interrupt number" and all low frequency timers share a single
47  * interrupt number.
48  *
49  * Index into this table is a platform-dependent interrupt A_INUM_* number.
50  */
51 LOCAL struct {
52     A_isr_t                isr;         /* function to call */
53     void                  *isr_arg;     /* argument to pass */
54 } cmnos_isr_info[NUM_DIRECT_INTR];
55
56
57
58 //int cmnos_invalid_isr_count; /* Track these for debug purposes */
59 LOCAL uint32_t cmnos_enabled_interrupts = 0; /* Shadows enabled interrupts */
60
61
62 LOCAL uint32_t cmnos_intr_dummy(void *pParm)
63 {
64     // dummy function in case any intr coming calling the null and crash
65 }
66
67 /*! - cmnos_intr_init
68  *
69  *  initialize all interrupt to diable, and setup all callback to dummy function
70  *  
71  *  p.s these are only level2 interrupt
72  */
73 LOCAL void
74 cmnos_intr_init(void)
75 {
76     uint32_t i=0;
77     
78     // disable all at init
79     cmnos_enabled_interrupts = 0;
80
81     // install the dummy function
82     for(i=0; i<NUM_DIRECT_INTR; i++)
83         cmnos_isr_info[i].isr = cmnos_intr_dummy;
84
85     // set intrenable to disable all
86     A_INTR_SET_INTRENABLE(cmnos_enabled_interrupts);
87
88 }
89
90
91 LOCAL void
92 cmnos_intr_mask_inum(uint32_t inum)
93 {
94     A_old_intr_t old_intr;
95     unsigned oldval;
96     int mask = 1 << inum;
97
98     A_INTR_DISABLE(&old_intr);
99     oldval = A_INTR_GET_INTRENABLE();
100     cmnos_enabled_interrupts &= ~mask;
101     oldval &= ~mask;
102     A_INTR_SET_INTRENABLE(oldval);
103     A_INTR_RESTORE(old_intr);
104 }
105
106 LOCAL void
107 cmnos_intr_unmask_inum(uint32_t inum)
108 {
109     A_old_intr_t old_intr;
110     unsigned oldval;
111     int unmask = 1 << inum;
112
113     A_INTR_DISABLE(&old_intr);
114     oldval = A_INTR_GET_INTRENABLE();
115     cmnos_enabled_interrupts |= unmask;
116 //    if (!pending_dsr) {
117         oldval |= unmask;
118 //    }
119     A_INTR_SET_INTRENABLE(oldval);
120     A_INTR_RESTORE(old_intr);
121 }
122
123
124 LOCAL void
125 cmnos_intr_attach_isr(uint32_t inum, A_isr_t isr, void *arg)
126 {
127     A_old_intr_t old_intr;
128
129     A_ASSERT(inum < NUM_DIRECT_INTR);
130     A_ASSERT(isr != NULL);
131
132      A_INTR_DISABLE(&old_intr);
133
134     cmnos_isr_info[inum].isr = isr;
135     cmnos_isr_info[inum].isr_arg = arg;
136
137     A_INTR_RESTORE(old_intr);
138 }
139
140 /*
141  * Invoke the ISR corresponding to an interrupt number.
142  * Note that we expect interrupts for the given interrupt
143  * number to be blocked when this function is called.  In
144  * fact, current ISRs assume that ALL non-fatal interrupts
145  * are blocked, and this allows the ISRs to avoid excessive
146  * calls to A_INTR_DISABLE/RESTORE which would otherwise be
147  * needed around calls to A_INTR_SET_INTRENABLE and such.
148  */
149 LOCAL uint32_t
150 cmnos_intr_invoke_isr(uint32_t inum)
151 {
152     A_ASSERT(inum < NUM_DIRECT_INTR);
153     A_ASSERT(cmnos_isr_info[inum].isr != NULL);
154
155 //    A_PRINTF("cmnos_intr_invoke_isr %d\n", inum);
156     
157     return cmnos_isr_info[inum].isr(cmnos_isr_info[inum].isr_arg);
158 }
159
160 /*
161  * NB: Whenever an "inum" is passed to an intr API, it is an A_INUM_*.
162  */
163 void
164 cmnos_intr_module_install(struct intr_api *tbl)
165 {
166     tbl->_intr_init                     = cmnos_intr_init;
167     tbl->_intr_invoke_isr               = cmnos_intr_invoke_isr;
168         tbl->_intr_attach_isr               = cmnos_intr_attach_isr;
169     tbl->_intr_mask_inum                = cmnos_intr_mask_inum;
170     tbl->_intr_unmask_inum              = cmnos_intr_unmask_inum;
171
172     /*
173      * Note: These are all supplied elsewhere with platform-specific functions:
174      *   tbl->_get_intrenable
175      *   tbl->_set_intrenable
176      *   tbl->_get_intrpending
177      *   tbl->_unblock_all_intrlvl
178      *   tbl->_intr_disable
179      *   tbl->_intr_restore
180      */
181 }
182 #endif /* SYSTEM_MODULE_INTR */
183