2 #include <ddekit/interrupt.h>
3 #include <ddekit/memory.h>
4 #include <ddekit/semaphore.h>
5 #include <ddekit/thread.h>
7 #ifdef DDEBUG_LEVEL_IRQ
9 #define DDEBUG DDEBUG_LEVEL_IRQ
18 void(*thread_init
)(void *);
19 void(*handler
)(void *);
24 struct ddekit_irq_s
*next
;
27 static struct ddekit_irq_s
*irqs
= 0;
28 static ddekit_lock_t lock
;
30 /******************************************************************************
32 *****************************************************************************/
35 static void ddekit_irq_lock(void);
36 static void ddekit_irq_unlock(void);
37 static struct ddekit_irq_s
* find_by_irq(int irq
);
38 static void ddekit_irq_remove(struct ddekit_irq_s
*irq_s
);
39 static void ddekit_irq_thread(void *data
);
41 /******************************************************************************
43 *****************************************************************************/
44 static void ddekit_irq_lock(void)
46 ddekit_lock_lock(&lock
);
49 /******************************************************************************
51 *****************************************************************************/
52 static void ddekit_irq_unlock(void)
54 ddekit_lock_unlock(&lock
);
57 /******************************************************************************
59 *****************************************************************************/
60 static struct ddekit_irq_s
* find_by_irq(int irq
)
62 struct ddekit_irq_s
* irq_s
;
80 /******************************************************************************
82 *****************************************************************************/
83 static void ddekit_irq_remove(struct ddekit_irq_s
*irq_s
)
85 struct ddekit_irq_s
*i
;
103 if (i
->next
== irq_s
) {
104 i
->next
= irq_s
->next
;
114 /******************************************************************************
115 * ddekit_irq_thread *
116 *****************************************************************************/
117 static void ddekit_irq_thread(void *data
)
119 /* For each IRQ line an own thread is started */
121 struct ddekit_irq_s
*irq_s
= (struct ddekit_irq_s
*) data
;
123 /* call IRQ thread init function */
124 irq_s
->thread_init(irq_s
->priv
);
129 DDEBUG_MSG_VERBOSE("wating for IRQ %d to occur", irq_s
->irq
);
130 ddekit_sem_down(irq_s
->sem
);
131 DDEBUG_MSG_VERBOSE("executing handler for IRQ %d", irq_s
->irq
);
132 irq_s
->handler(irq_s
->priv
);
138 /******************************************************************************
139 * DDEKIT public API (include/dde/ddekit) *
140 *****************************************************************************/
142 /******************************************************************************
143 * ddekit_interrupt_attach *
144 *****************************************************************************/
145 ddekit_thread_t
*ddekit_interrupt_attach(int irq
,
147 void(*thread_init
)(void *),
148 void(*handler
)(void *),
151 struct ddekit_irq_s
*irq_s
;
153 irq_s
= (struct ddekit_irq_s
*)
154 ddekit_simple_malloc(sizeof(struct ddekit_irq_s
));
156 irq_s
->sem
= ddekit_sem_init(0);
158 irq_s
->irq_hook
= irq
;
159 irq_s
->shared
= shared
;
160 irq_s
->thread_init
= thread_init
;
161 irq_s
->handler
= handler
;
166 /* create interrupt thread */
167 snprintf(name
, 32, "ddekit_irq_%d",irq
);
168 irq_s
->th
= ddekit_thread_create(ddekit_irq_thread
, irq_s
, name
);
171 sys_irqsetpolicy(irq
,
172 0, /* not automatically re-enable interupts */
175 /* add to IRQ list */
181 DDEBUG_MSG_INFO("Attached to irq %d (hook: %d)", irq
, irq_s
->irq_hook
);
186 /******************************************************************************
187 * ddekit_interrupt_detach *
188 *****************************************************************************/
189 void ddekit_interrupt_detach(int irq
)
191 struct ddekit_irq_s
*irq_s
;
193 irq_s
= find_by_irq(irq
);
195 sys_irqrmpolicy(&irq_s
->irq_hook
);
197 ddekit_thread_terminate(irq_s
->th
);
198 ddekit_irq_remove(irq_s
);
199 ddekit_simple_free(irq_s
);
200 DDEBUG_MSG_VERBOSE(" IRQ %d", irq
);
203 /******************************************************************************
204 * ddekit_interrupt_disable *
205 *****************************************************************************/
206 void ddekit_interrupt_disable(int irq
)
208 struct ddekit_irq_s
*irq_s
;
209 irq_s
= find_by_irq(irq
);
211 //sys_irqdisable(&irq_s->irq_hook);
212 DDEBUG_MSG_VERBOSE(" IRQ %d", irq
);
215 /******************************************************************************
216 * ddekit_interrupt_enable *
217 *****************************************************************************/
218 void ddekit_interrupt_enable(int irq
)
220 struct ddekit_irq_s
*irq_s
;
221 irq_s
= find_by_irq(irq
);
223 //sys_irqenable(&irq_s->irq_hook);
224 DDEBUG_MSG_VERBOSE(" IRQ %d", irq
);
227 /******************************************************************************
229 *****************************************************************************/
230 void ddekit_init_irqs()
232 ddekit_lock_init(&lock
);
235 /******************************************************************************
236 * DDEKIT internals (src/irq.h) *
237 *****************************************************************************/
239 /******************************************************************************
240 * _ddekit_interrupt_trigger *
241 *****************************************************************************/
242 void _ddekit_interrupt_trigger(int irq
)
244 struct ddekit_irq_s
*irq_s
;
246 irq_s
= find_by_irq(irq
);
249 DDEBUG_MSG_VERBOSE("Triggering IRQ %d", irq
);
250 ddekit_sem_up(irq_s
->sem
);
251 sys_irqenable(&irq_s
->irq_hook
);
253 DDEBUG_MSG_WARN("no handler for IRQ %d", irq
);