1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/config.h>
21#include <linux/ptrace.h>
22#include <linux/kernel_stat.h>
23#include <linux/signal.h>
24#include <linux/sched.h>
25#include <linux/ioport.h>
26#include <linux/interrupt.h>
27#include <linux/slab.h>
28#include <linux/random.h>
29#include <linux/smp.h>
30#include <linux/list.h>
31#include <linux/timer.h>
32#include <linux/init.h>
33
34#include <asm/irq.h>
35#include <asm/system.h>
36#include <asm/mach/irq.h>
37
38#include <asm/arch/irq.h>
39
40
41
42
43
44
45
46
47#define MAX_IRQ_CNT 100000
48
49static volatile unsigned long irq_err_count;
50static spinlock_t irq_controller_lock;
51static LIST_HEAD(irq_pending);
52
53struct irqdesc irq_desc[NR_IRQS];
54void (*init_arch_irq)(void) __initdata = NULL;
55
56
57
58
59static void dummy_mask_unmask_irq(unsigned int irq)
60{
61}
62
63
64
65
66#ifndef irq_finish
67#define irq_finish(irq) do { } while (0)
68#endif
69
70
71
72
73
74
75
76
77
78void disable_irq(unsigned int irq)
79{
80 struct irqdesc *desc = irq_desc + irq;
81 unsigned long flags;
82
83 spin_lock_irqsave(&irq_controller_lock, flags);
84 if (!desc->disable_depth++) {
85#ifndef CONFIG_CPU_SA1100
86 desc->mask(irq);
87#endif
88 }
89 spin_unlock_irqrestore(&irq_controller_lock, flags);
90}
91
92
93
94
95
96
97
98
99
100
101
102void enable_irq(unsigned int irq)
103{
104 struct irqdesc *desc = irq_desc + irq;
105 unsigned long flags;
106
107 spin_lock_irqsave(&irq_controller_lock, flags);
108 if (!desc->disable_depth) {
109 printk("enable_irq(%u) unbalanced from %p\n", irq,
110 __builtin_return_address(0));
111 } else if (!--desc->disable_depth) {
112 desc->probing = 0;
113 desc->unmask(irq);
114
115
116
117
118
119
120
121 if (desc->pending) {
122 desc->pending = 0;
123 if (list_empty(&desc->pend))
124 list_add(&desc->pend, &irq_pending);
125 }
126 }
127 spin_unlock_irqrestore(&irq_controller_lock, flags);
128}
129
130int get_irq_list(char *buf)
131{
132 int i;
133 struct irqaction * action;
134 char *p = buf;
135
136 for (i = 0 ; i < NR_IRQS ; i++) {
137 action = irq_desc[i].action;
138 if (!action)
139 continue;
140 p += sprintf(p, "%3d: %10u ", i, kstat_irqs(i));
141 p += sprintf(p, " %s", action->name);
142 for (action = action->next; action; action = action->next) {
143 p += sprintf(p, ", %s", action->name);
144 }
145 *p++ = '\n';
146 }
147
148#ifdef CONFIG_ARCH_ACORN
149 p += get_fiq_list(p);
150#endif
151 p += sprintf(p, "Err: %10lu\n", irq_err_count);
152 return p - buf;
153}
154
155
156
157
158
159
160
161
162
163static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
164{
165 unsigned long instr_ptr = instruction_pointer(regs);
166
167 if (desc->lck_jif == jiffies &&
168 desc->lck_pc >= instr_ptr && desc->lck_pc < instr_ptr + 8) {
169 desc->lck_cnt += 1;
170
171 if (desc->lck_cnt > MAX_IRQ_CNT) {
172 if (!desc->lck_warned++)
173 printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
174 mod_timer(&desc->lck_timer, jiffies + 10*HZ);
175 return 1;
176 }
177 } else {
178 desc->lck_cnt = 0;
179 desc->lck_pc = instruction_pointer(regs);
180 desc->lck_jif = jiffies;
181 if (desc->lck_warned < 0)
182 desc->lck_warned ++;
183 }
184 return 0;
185}
186
187static void
188__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
189{
190 unsigned int status;
191
192 spin_unlock(&irq_controller_lock);
193
194 if (!(action->flags & SA_INTERRUPT))
195 local_irq_enable();
196
197 status = 0;
198 do {
199 status |= action->flags;
200 action->handler(irq, action->dev_id, regs);
201 action = action->next;
202 } while (action);
203
204 if (status & SA_SAMPLE_RANDOM)
205 add_interrupt_randomness(irq);
206
207 spin_lock_irq(&irq_controller_lock);
208}
209
210
211
212
213void do_IRQ(int irq, struct pt_regs * regs)
214{
215 struct irqdesc *desc = irq_desc + irq;
216
217 desc->triggered = 1;
218
219
220
221
222
223 desc->mask_ack(irq);
224
225
226
227
228
229
230 if (desc->running || desc->disable_depth)
231 goto running;
232
233
234
235
236 desc->running = 1;
237
238 kstat.irqs[smp_processor_id()][irq]++;
239
240 do {
241 struct irqaction *action;
242
243 action = desc->action;
244 if (!action)
245 break;
246
247 if (desc->pending && desc->disable_depth == 0) {
248 desc->pending = 0;
249 desc->unmask(irq);
250 }
251
252 __do_irq(irq, action, regs);
253 } while (desc->pending && desc->disable_depth == 0);
254
255 desc->running = 0;
256
257
258
259
260 if (desc->action && !check_irq_lock(desc, irq, regs))
261 desc->unmask(irq);
262 return;
263
264 running:
265
266
267
268
269 desc->pending = 1;
270}
271
272static void do_pending_irqs(struct pt_regs *regs)
273{
274 struct list_head head, *l, *n;
275
276 do {
277 struct irqdesc *desc;
278
279
280
281
282
283
284 head = irq_pending;
285 INIT_LIST_HEAD(&irq_pending);
286 head.next->prev = &head;
287 head.prev->next = &head;
288
289
290
291
292
293 list_for_each_safe(l, n, &head) {
294 desc = list_entry(l, struct irqdesc, pend);
295 list_del_init(&desc->pend);
296 do_IRQ(desc - irq_desc, regs);
297 }
298
299
300
301
302 BUG_ON(!list_empty(&head));
303 } while (!list_empty(&irq_pending));
304}
305
306
307
308
309
310
311asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs)
312{
313 irq = fixup_irq(irq);
314
315
316
317
318
319 if (irq < NR_IRQS) {
320 int cpu = smp_processor_id();
321
322 irq_enter(cpu, irq);
323 spin_lock(&irq_controller_lock);
324 do_IRQ(irq, regs);
325
326
327
328
329 if (!list_empty(&irq_pending))
330 do_pending_irqs(regs);
331
332 spin_unlock(&irq_controller_lock);
333 irq_exit(cpu, irq);
334
335 if (softirq_pending(cpu))
336 do_softirq();
337
338 irq_finish(irq);
339 return;
340 }
341
342 irq_err_count += 1;
343 printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
344
345 irq_finish(irq);
346 return;
347}
348
349static void irqlck_timeout(unsigned long _data)
350{
351 struct irqdesc *desc = (struct irqdesc *)_data;
352
353 spin_lock(&irq_controller_lock);
354
355 del_timer(&desc->lck_timer);
356
357 desc->lck_cnt = 0;
358 desc->lck_pc = 0;
359 desc->lck_jif = 0;
360 desc->lck_warned = -10;
361
362 if (desc->disable_depth == 0)
363 desc->unmask(desc - irq_desc);
364
365 spin_unlock(&irq_controller_lock);
366}
367
368#ifdef CONFIG_ARCH_ACORN
369void do_ecard_IRQ(int irq, struct pt_regs *regs)
370{
371 struct irqdesc * desc;
372 struct irqaction * action;
373 int cpu;
374
375 desc = irq_desc + irq;
376
377 cpu = smp_processor_id();
378 kstat.irqs[cpu][irq]++;
379 desc->triggered = 1;
380
381 action = desc->action;
382
383 if (action) {
384 do {
385 action->handler(irq, action->dev_id, regs);
386 action = action->next;
387 } while (action);
388 } else {
389 spin_lock(&irq_controller_lock);
390 desc->mask(irq);
391 spin_unlock(&irq_controller_lock);
392 }
393}
394#endif
395
396int setup_arm_irq(int irq, struct irqaction * new)
397{
398 int shared = 0;
399 struct irqaction *old, **p;
400 unsigned long flags;
401 struct irqdesc *desc;
402
403
404
405
406
407
408 if (new->flags & SA_SAMPLE_RANDOM) {
409
410
411
412
413
414
415
416
417 rand_initialize_irq(irq);
418 }
419
420
421
422
423 desc = irq_desc + irq;
424 spin_lock_irqsave(&irq_controller_lock, flags);
425 p = &desc->action;
426 if ((old = *p) != NULL) {
427
428 if (!(old->flags & new->flags & SA_SHIRQ)) {
429 spin_unlock_irqrestore(&irq_controller_lock, flags);
430 return -EBUSY;
431 }
432
433
434 do {
435 p = &old->next;
436 old = *p;
437 } while (old);
438 shared = 1;
439 }
440
441 *p = new;
442
443 if (!shared) {
444 desc->probing = 0;
445 desc->running = 0;
446 desc->pending = 0;
447 desc->disable_depth = 1;
448 if (!desc->noautoenable) {
449 desc->disable_depth = 0;
450 desc->unmask(irq);
451 }
452 }
453
454 spin_unlock_irqrestore(&irq_controller_lock, flags);
455 return 0;
456}
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
490 unsigned long irq_flags, const char * devname, void *dev_id)
491{
492 unsigned long retval;
493 struct irqaction *action;
494
495 if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
496 (irq_flags & SA_SHIRQ && !dev_id))
497 return -EINVAL;
498
499 action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
500 if (!action)
501 return -ENOMEM;
502
503 action->handler = handler;
504 action->flags = irq_flags;
505 action->mask = 0;
506 action->name = devname;
507 action->next = NULL;
508 action->dev_id = dev_id;
509
510 retval = setup_arm_irq(irq, action);
511
512 if (retval)
513 kfree(action);
514 return retval;
515}
516
517
518
519
520
521
522
523
524
525
526
527
528
529void free_irq(unsigned int irq, void *dev_id)
530{
531 struct irqaction * action, **p;
532 unsigned long flags;
533
534 if (irq >= NR_IRQS || !irq_desc[irq].valid) {
535 printk(KERN_ERR "Trying to free IRQ%d\n",irq);
536#ifdef CONFIG_DEBUG_ERRORS
537 __backtrace();
538#endif
539 return;
540 }
541
542 spin_lock_irqsave(&irq_controller_lock, flags);
543 for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
544 if (action->dev_id != dev_id)
545 continue;
546
547
548 *p = action->next;
549 kfree(action);
550 goto out;
551 }
552 printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
553#ifdef CONFIG_DEBUG_ERRORS
554 __backtrace();
555#endif
556out:
557 spin_unlock_irqrestore(&irq_controller_lock, flags);
558}
559
560static DECLARE_MUTEX(probe_sem);
561
562
563
564
565
566
567
568unsigned long probe_irq_on(void)
569{
570 unsigned int i, irqs = 0;
571 unsigned long delay;
572
573 down(&probe_sem);
574
575
576
577
578
579 spin_lock_irq(&irq_controller_lock);
580 for (i = 0; i < NR_IRQS; i++) {
581 if (!irq_desc[i].probe_ok || irq_desc[i].action)
582 continue;
583
584 irq_desc[i].probing = 1;
585 irq_desc[i].triggered = 0;
586 irq_desc[i].unmask(i);
587 irqs += 1;
588 }
589 spin_unlock_irq(&irq_controller_lock);
590
591
592
593
594 for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
595 ;
596
597
598
599
600 spin_lock_irq(&irq_controller_lock);
601 for (i = 0; i < NR_IRQS; i++) {
602 if (irq_desc[i].probing && irq_desc[i].triggered) {
603 irq_desc[i].probing = 0;
604 irqs -= 1;
605 }
606 }
607 spin_unlock_irq(&irq_controller_lock);
608
609 return irqs;
610}
611
612unsigned int probe_irq_mask(unsigned long irqs)
613{
614 unsigned int mask = 0, i;
615
616 spin_lock_irq(&irq_controller_lock);
617 for (i = 0; i < 16 && i < NR_IRQS; i++)
618 if (irq_desc[i].probing && irq_desc[i].triggered)
619 mask |= 1 << i;
620 spin_unlock_irq(&irq_controller_lock);
621
622 up(&probe_sem);
623
624 return mask;
625}
626
627
628
629
630
631
632int probe_irq_off(unsigned long irqs)
633{
634 unsigned int i;
635 int irq_found = NO_IRQ;
636
637
638
639
640
641 spin_lock_irq(&irq_controller_lock);
642 for (i = 0; i < NR_IRQS; i++) {
643 if (irq_desc[i].probing &&
644 irq_desc[i].triggered) {
645 if (irq_found != NO_IRQ) {
646 irq_found = NO_IRQ;
647 goto out;
648 }
649 irq_found = i;
650 }
651 }
652
653 if (irq_found == -1)
654 irq_found = NO_IRQ;
655out:
656 spin_unlock_irq(&irq_controller_lock);
657
658 up(&probe_sem);
659
660 return irq_found;
661}
662
663void __init init_irq_proc(void)
664{
665}
666
667void __init init_IRQ(void)
668{
669 extern void init_dma(void);
670 int irq;
671
672 for (irq = 0; irq < NR_IRQS; irq++) {
673 irq_desc[irq].disable_depth = 1;
674 irq_desc[irq].probe_ok = 0;
675 irq_desc[irq].valid = 0;
676 irq_desc[irq].noautoenable = 0;
677 irq_desc[irq].mask_ack = dummy_mask_unmask_irq;
678 irq_desc[irq].mask = dummy_mask_unmask_irq;
679 irq_desc[irq].unmask = dummy_mask_unmask_irq;
680 INIT_LIST_HEAD(&irq_desc[irq].pend);
681 init_timer(&irq_desc[irq].lck_timer);
682 irq_desc[irq].lck_timer.data = (unsigned long)&irq_desc[irq];
683 irq_desc[irq].lck_timer.function = irqlck_timeout;
684 }
685
686 init_arch_irq();
687 init_dma();
688}
689