00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <linux/interrupt.h>
00013 #include <linux/string.h>
00014
00015
00016 #include <l4/dde/ddekit/interrupt.h>
00017 #include <l4/dde/ddekit/memory.h>
00018
00019
00020 #include "dde26.h"
00021 #include "local.h"
00022
00023
00024 irq_cpustat_t irq_stat[CONFIG_NR_CPUS];
00025
00026
00027
00028
00029 static struct dde_irq
00030 {
00031 unsigned irq;
00032 unsigned count;
00033 int shared;
00034 struct ddekit_thread *thread;
00035 struct irqaction *action;
00036
00037 struct dde_irq *next;
00038 } *used_irqs;
00039
00040
00041 static void irq_thread_init(void *p) {
00042 l4dde26_process_add_worker(); }
00043
00044
00045 extern ddekit_sem_t *dde_softirq_sem;
00046 static void irq_handler(void *arg)
00047 {
00048 struct dde_irq *irq = arg;
00049 struct irqaction *action;
00050
00051 #if 0
00052 DEBUG_MSG("irq 0x%x", irq->irq);
00053 #endif
00054
00055 for (action = irq->action; action; action = action->next) {
00056 irqreturn_t r = action->handler(action->irq, action->dev_id);
00057 #if 0
00058 DEBUG_MSG("return: %s", r == IRQ_HANDLED ? "IRQ_HANDLED" : r == IRQ_NONE ? "IRQ_NONE" : "??");
00059 #endif
00060 }
00061
00062
00063 if (local_softirq_pending())
00064 ddekit_sem_up(dde_softirq_sem);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static int claim_irq(struct irqaction *action)
00081 {
00082 int shared = action->flags & IRQF_SHARED ? 1 : 0;
00083 struct dde_irq *irq;
00084
00085
00086 for (irq = used_irqs; irq; irq = irq->next)
00087 if (irq->irq == action->irq) break;
00088
00089
00090 if (!irq) {
00091
00092 irq = ddekit_simple_malloc(sizeof(*irq));
00093 if (!irq) return -ENOMEM;
00094 memset(irq, 0, sizeof(*irq));
00095
00096 irq->irq = action->irq;
00097 irq->shared = shared;
00098 irq->next = used_irqs;
00099 used_irqs = irq;
00100
00101
00102 irq->thread = ddekit_interrupt_attach(irq->irq,
00103 irq->shared,
00104 irq_thread_init,
00105 irq_handler,
00106 (void *)irq);
00107 if (!irq->thread) {
00108 ddekit_simple_free(irq);
00109 return -EBUSY;
00110 }
00111 }
00112
00113
00114 if ((!irq->shared || !shared) && irq->action) return -EBUSY;
00115
00116
00117 irq->count++;
00118 action->next = irq->action;
00119 irq->action = action;
00120
00121 return irq->count;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 static struct irqaction *release_irq(unsigned irq_num, void *dev_id)
00131 {
00132 struct dde_irq *prev_irq, *irq;
00133
00134
00135 for (prev_irq = 0, irq = used_irqs; irq;
00136 prev_irq = irq, irq = irq->next)
00137 if (irq->irq == irq_num) break;
00138
00139 if (!irq) return 0;
00140
00141 struct irqaction *prev_action, *action;
00142
00143 for (prev_action = 0, action = irq->action; action;
00144 prev_action = action, action = action->next)
00145 if (action->dev_id == dev_id) break;
00146
00147 if (!action) return 0;
00148
00149
00150 if (prev_action)
00151 prev_action->next = action->next;
00152 else
00153 irq->action = action->next;
00154
00155
00156
00157 if (!irq->action) {
00158 if (prev_irq)
00159 prev_irq->next = irq->next;
00160 else
00161 used_irqs = irq->next;
00162
00163
00164 ddekit_interrupt_detach(irq->irq);
00165
00166 ddekit_simple_free(irq);
00167 }
00168
00169 return action;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 int request_irq(unsigned int irq, irq_handler_t handler,
00191 unsigned long flags, const char *dev_name, void *dev_id)
00192 {
00193 if (!handler) return -EINVAL;
00194
00195
00196 struct irqaction *irq_action = ddekit_simple_malloc(sizeof(*irq_action));
00197 if (!irq_action) return -ENOMEM;
00198 memset(irq_action, 0, sizeof(*irq_action));
00199
00200 irq_action->handler = handler;
00201 irq_action->flags = flags;
00202 irq_action->name = dev_name;
00203 irq_action->dev_id = dev_id;
00204 irq_action->irq = irq;
00205
00206
00207 int err = claim_irq(irq_action);
00208 if (err < 0) return err;
00209
00210 return 0;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 void free_irq(unsigned int irq, void *dev_id)
00221 {
00222 struct irqaction *irq_action = release_irq(irq, dev_id);
00223
00224 if (irq_action)
00225 ddekit_simple_free(irq_action);
00226 }
00227
00228 void disable_irq(unsigned int irq)
00229 {
00230 ddekit_interrupt_disable(irq);
00231 }
00232
00233 void disable_irq_nosync(unsigned int irq)
00234 {
00235
00236
00237
00238
00239
00240
00241 ddekit_interrupt_disable(irq);
00242 }
00243
00244 void enable_irq(unsigned int irq)
00245 {
00246 ddekit_interrupt_enable(irq);
00247 }