1 #ifndef __ALT_LEGACY_IRQ_H__
2 #define __ALT_LEGACY_IRQ_H__
3 
4 /******************************************************************************
5 *                                                                             *
6 * License Agreement                                                           *
7 *                                                                             *
8 * Copyright (c) 2009 Altera Corporation, San Jose, California, USA.           *
9 * All rights reserved.                                                        *
10 *                                                                             *
11 * Permission is hereby granted, free of charge, to any person obtaining a     *
12 * copy of this software and associated documentation files (the "Software"),  *
13 * to deal in the Software without restriction, including without limitation   *
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
15 * and/or sell copies of the Software, and to permit persons to whom the       *
16 * Software is furnished to do so, subject to the following conditions:        *
17 *                                                                             *
18 * The above copyright notice and this permission notice shall be included in  *
19 * all copies or substantial portions of the Software.                         *
20 *                                                                             *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
27 * DEALINGS IN THE SOFTWARE.                                                   *
28 *                                                                             *
29 *                                                                             *
30 ******************************************************************************/
31 
32 /*
33  * This file provides prototypes and inline implementations of certain routines
34  * used by the legacy interrupt API. Do not include this in your driver or
35  * application source files, use "sys/alt_irq.h" instead to access the proper
36  * public API.
37  */
38 
39 #include <errno.h>
40 #include "system.h"
41 
42 #ifndef NIOS2_EIC_PRESENT
43 
44 #include "nios2.h"
45 #include "alt_types.h"
46 
47 #include "sys/alt_irq.h"
48 
49 #ifdef __cplusplus
50 extern "C"
51 {
52 #endif /* __cplusplus */
53 
54 /*
55  * alt_irq_register() can be used to register an interrupt handler. If the
56  * function is succesful, then the requested interrupt will be enabled upon
57  * return.
58  */
59 extern int alt_irq_register (alt_u32 id,
60                              void*   context,
61                              alt_isr_func handler);
62 
63 /*
64  * alt_irq_disable() disables the individual interrupt indicated by "id".
65  */
alt_irq_disable(alt_u32 id)66 static ALT_INLINE int ALT_ALWAYS_INLINE alt_irq_disable (alt_u32 id)
67 {
68   alt_irq_context  status;
69   extern volatile alt_u32 alt_irq_active;
70 
71   status = alt_irq_disable_all ();
72 
73   alt_irq_active &= ~(1 << id);
74   NIOS2_WRITE_IENABLE (alt_irq_active);
75 
76   alt_irq_enable_all(status);
77 
78   return 0;
79 }
80 
81 /*
82  * alt_irq_enable() enables the individual interrupt indicated by "id".
83  */
alt_irq_enable(alt_u32 id)84 static ALT_INLINE int ALT_ALWAYS_INLINE alt_irq_enable (alt_u32 id)
85 {
86   alt_irq_context  status;
87   extern volatile alt_u32 alt_irq_active;
88 
89   status = alt_irq_disable_all ();
90 
91   alt_irq_active |= (1 << id);
92   NIOS2_WRITE_IENABLE (alt_irq_active);
93 
94   alt_irq_enable_all(status);
95 
96   return 0;
97 }
98 
99 #ifndef ALT_EXCEPTION_STACK
100 /*
101  * alt_irq_initerruptable() should only be called from within an ISR. It is used
102  * to allow higer priority interrupts to interrupt the current ISR. The input
103  * argument, "priority", is the priority, i.e. interrupt number of the current
104  * interrupt.
105  *
106  * If this function is called, then the ISR is required to make a call to
107  * alt_irq_non_interruptible() before returning. The input argument to
108  * alt_irq_non_interruptible() is the return value from alt_irq_interruptible().
109  *
110  * Care should be taken when using this pair of functions, since they increasing
111  * the system overhead associated with interrupt handling.
112  *
113  * If you are using an exception stack then nested interrupts won't work, so
114  * these functions are not available in that case.
115  */
alt_irq_interruptible(alt_u32 priority)116 static ALT_INLINE alt_u32 ALT_ALWAYS_INLINE alt_irq_interruptible (alt_u32 priority)
117 {
118   extern volatile alt_u32 alt_priority_mask;
119   extern volatile alt_u32 alt_irq_active;
120 
121   alt_u32 old_priority;
122 
123   old_priority      = alt_priority_mask;
124   alt_priority_mask = (1 << priority) - 1;
125 
126   NIOS2_WRITE_IENABLE (alt_irq_active & alt_priority_mask);
127 
128   NIOS2_WRITE_STATUS (1);
129 
130   return old_priority;
131 }
132 
133 /*
134  * See Comments above for alt_irq_interruptible() for an explanation of the use of this
135  * function.
136  */
alt_irq_non_interruptible(alt_u32 mask)137 static ALT_INLINE void ALT_ALWAYS_INLINE alt_irq_non_interruptible (alt_u32 mask)
138 {
139   extern volatile alt_u32 alt_priority_mask;
140   extern volatile alt_u32 alt_irq_active;
141 
142   NIOS2_WRITE_STATUS (0);
143 
144   alt_priority_mask = mask;
145 
146   NIOS2_WRITE_IENABLE (mask & alt_irq_active);
147 }
148 #endif /* ALT_EXCEPTION_STACK */
149 
150 #ifdef __cplusplus
151 }
152 #endif /* __cplusplus */
153 
154 #endif /* NIOS2_EIC_PRESENT */
155 
156 #endif /* __ALT_LEGACY_IRQ_H__ */
157