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