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/errno.h>
23#include <linux/signal.h>
24#include <linux/sched.h>
25#include <linux/ioport.h>
26#include <linux/interrupt.h>
27#include <linux/timex.h>
28#include <linux/slab.h>
29#include <linux/random.h>
30#include <linux/smp_lock.h>
31#include <linux/init.h>
32#include <linux/kernel_stat.h>
33#include <linux/irq.h>
34#include <linux/proc_fs.h>
35
36#include <asm/atomic.h>
37#include <asm/io.h>
38#include <asm/smp.h>
39#include <asm/system.h>
40#include <asm/bitops.h>
41#include <asm/uaccess.h>
42#include <asm/pgalloc.h>
43#include <asm/delay.h>
44#include <asm/desc.h>
45#include <asm/irq.h>
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
69 { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
70
71static void register_irq_proc (unsigned int irq);
72
73
74
75
76
77void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
78
79
80
81
82
83static void enable_none(unsigned int irq) { }
84static unsigned int startup_none(unsigned int irq) { return 0; }
85static void disable_none(unsigned int irq) { }
86static void ack_none(unsigned int irq)
87{
88
89
90
91
92
93#if CONFIG_X86
94 printk("unexpected IRQ trap at vector %02x\n", irq);
95#ifdef CONFIG_X86_LOCAL_APIC
96
97
98
99
100
101
102
103
104 ack_APIC_irq();
105#endif
106#endif
107}
108
109
110#define shutdown_none disable_none
111#define end_none enable_none
112
113struct hw_interrupt_type no_irq_type = {
114 "none",
115 startup_none,
116 shutdown_none,
117 enable_none,
118 disable_none,
119 ack_none,
120 end_none
121};
122
123atomic_t irq_err_count;
124#ifdef CONFIG_X86_IO_APIC
125#ifdef APIC_MISMATCH_DEBUG
126atomic_t irq_mis_count;
127#endif
128#endif
129
130
131
132
133
134int get_irq_list(char *buf)
135{
136 int i, j;
137 struct irqaction * action;
138 char *p = buf;
139
140 p += sprintf(p, " ");
141 for (j=0; j<smp_num_cpus; j++)
142 p += sprintf(p, "CPU%d ",j);
143 *p++ = '\n';
144
145 for (i = 0 ; i < NR_IRQS ; i++) {
146 action = irq_desc[i].action;
147 if (!action)
148 continue;
149 p += sprintf(p, "%3d: ",i);
150#ifndef CONFIG_SMP
151 p += sprintf(p, "%10u ", kstat_irqs(i));
152#else
153 for (j = 0; j < smp_num_cpus; j++)
154 p += sprintf(p, "%10u ",
155 kstat.irqs[cpu_logical_map(j)][i]);
156#endif
157 p += sprintf(p, " %14s", irq_desc[i].handler->typename);
158 p += sprintf(p, " %s", action->name);
159
160 for (action=action->next; action; action = action->next)
161 p += sprintf(p, ", %s", action->name);
162 *p++ = '\n';
163 }
164 p += sprintf(p, "NMI: ");
165 for (j = 0; j < smp_num_cpus; j++)
166 p += sprintf(p, "%10u ",
167 nmi_count(cpu_logical_map(j)));
168 p += sprintf(p, "\n");
169#if CONFIG_X86_LOCAL_APIC
170 p += sprintf(p, "LOC: ");
171 for (j = 0; j < smp_num_cpus; j++)
172 p += sprintf(p, "%10u ",
173 apic_timer_irqs[cpu_logical_map(j)]);
174 p += sprintf(p, "\n");
175#endif
176 p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
177#ifdef CONFIG_X86_IO_APIC
178#ifdef APIC_MISMATCH_DEBUG
179 p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
180#endif
181#endif
182 return p - buf;
183}
184
185
186
187
188
189
190
191#ifdef CONFIG_SMP
192unsigned char global_irq_holder = NO_PROC_ID;
193unsigned volatile long global_irq_lock;
194
195extern void show_stack(unsigned long* esp);
196
197static void show(char * str)
198{
199 int i;
200 int cpu = smp_processor_id();
201
202 printk("\n%s, CPU %d:\n", str, cpu);
203 printk("irq: %d [",irqs_running());
204 for(i=0;i < smp_num_cpus;i++)
205 printk(" %d",local_irq_count(i));
206 printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
207 for(i=0;i < smp_num_cpus;i++)
208 printk(" %d",local_bh_count(i));
209
210 printk(" ]\nStack dumps:");
211 for(i = 0; i < smp_num_cpus; i++) {
212 unsigned long esp;
213 if (i == cpu)
214 continue;
215 printk("\nCPU %d:",i);
216 esp = init_tss[i].esp0;
217 if (!esp) {
218
219
220
221
222 printk(" <unknown> ");
223 continue;
224 }
225 esp &= ~(THREAD_SIZE-1);
226 esp += sizeof(struct task_struct);
227 show_stack((void*)esp);
228 }
229 printk("\nCPU %d:",cpu);
230 show_stack(NULL);
231 printk("\n");
232}
233
234#define MAXCOUNT 100000000
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
253
254#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
255# define SYNC_OTHER_CORES(x) udelay(x+1)
256#else
257
258
259
260# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
261#endif
262
263static inline void wait_on_irq(int cpu)
264{
265 int count = MAXCOUNT;
266
267 for (;;) {
268
269
270
271
272
273
274 if (!irqs_running())
275 if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
276 break;
277
278
279 clear_bit(0,&global_irq_lock);
280
281 for (;;) {
282 if (!--count) {
283 show("wait_on_irq");
284 count = ~0;
285 }
286 __sti();
287 SYNC_OTHER_CORES(cpu);
288 __cli();
289 if (irqs_running())
290 continue;
291 if (global_irq_lock)
292 continue;
293 if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
294 continue;
295 if (!test_and_set_bit(0,&global_irq_lock))
296 break;
297 }
298 }
299}
300
301
302
303
304
305
306
307
308void synchronize_irq(void)
309{
310 if (irqs_running()) {
311
312 cli();
313 sti();
314 }
315}
316
317static inline void get_irqlock(int cpu)
318{
319 if (test_and_set_bit(0,&global_irq_lock)) {
320
321 if ((unsigned char) cpu == global_irq_holder)
322 return;
323
324 do {
325 do {
326 rep_nop();
327 } while (test_bit(0,&global_irq_lock));
328 } while (test_and_set_bit(0,&global_irq_lock));
329 }
330
331
332
333
334 wait_on_irq(cpu);
335
336
337
338
339 global_irq_holder = cpu;
340}
341
342#define EFLAGS_IF_SHIFT 9
343
344
345
346
347
348
349
350
351
352
353
354
355
356void __global_cli(void)
357{
358 unsigned int flags;
359
360 __save_flags(flags);
361 if (flags & (1 << EFLAGS_IF_SHIFT)) {
362 int cpu = smp_processor_id();
363 __cli();
364 if (!local_irq_count(cpu))
365 get_irqlock(cpu);
366 }
367}
368
369void __global_sti(void)
370{
371 int cpu = smp_processor_id();
372
373 if (!local_irq_count(cpu))
374 release_irqlock(cpu);
375 __sti();
376}
377
378
379
380
381
382
383
384
385unsigned long __global_save_flags(void)
386{
387 int retval;
388 int local_enabled;
389 unsigned long flags;
390 int cpu = smp_processor_id();
391
392 __save_flags(flags);
393 local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
394
395 retval = 2 + local_enabled;
396
397
398 if (!local_irq_count(cpu)) {
399 if (local_enabled)
400 retval = 1;
401 if (global_irq_holder == cpu)
402 retval = 0;
403 }
404 return retval;
405}
406
407void __global_restore_flags(unsigned long flags)
408{
409 switch (flags) {
410 case 0:
411 __global_cli();
412 break;
413 case 1:
414 __global_sti();
415 break;
416 case 2:
417 __cli();
418 break;
419 case 3:
420 __sti();
421 break;
422 default:
423 printk("global_restore_flags: %08lx (%08lx)\n",
424 flags, (&flags)[-1]);
425 }
426}
427
428#endif
429
430
431
432
433
434
435
436
437int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
438{
439 int status;
440 int cpu = smp_processor_id();
441
442 irq_enter(cpu, irq);
443
444 status = 1;
445
446 if (!(action->flags & SA_INTERRUPT))
447 __sti();
448
449 do {
450 status |= action->flags;
451 action->handler(irq, action->dev_id, regs);
452 action = action->next;
453 } while (action);
454 if (status & SA_SAMPLE_RANDOM)
455 add_interrupt_randomness(irq);
456 __cli();
457
458 irq_exit(cpu, irq);
459
460 return status;
461}
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482inline void disable_irq_nosync(unsigned int irq)
483{
484 irq_desc_t *desc = irq_desc + irq;
485 unsigned long flags;
486
487 spin_lock_irqsave(&desc->lock, flags);
488 if (!desc->depth++) {
489 desc->status |= IRQ_DISABLED;
490 desc->handler->disable(irq);
491 }
492 spin_unlock_irqrestore(&desc->lock, flags);
493}
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508void disable_irq(unsigned int irq)
509{
510 disable_irq_nosync(irq);
511
512 if (!local_irq_count(smp_processor_id())) {
513 do {
514 barrier();
515 cpu_relax();
516 } while (irq_desc[irq].status & IRQ_INPROGRESS);
517 }
518}
519
520
521
522
523
524
525
526
527
528
529
530
531void enable_irq(unsigned int irq)
532{
533 irq_desc_t *desc = irq_desc + irq;
534 unsigned long flags;
535
536 spin_lock_irqsave(&desc->lock, flags);
537 switch (desc->depth) {
538 case 1: {
539 unsigned int status = desc->status & ~IRQ_DISABLED;
540 desc->status = status;
541 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
542 desc->status = status | IRQ_REPLAY;
543 hw_resend_irq(desc->handler,irq);
544 }
545 desc->handler->enable(irq);
546
547 }
548 default:
549 desc->depth--;
550 break;
551 case 0:
552 printk("enable_irq(%u) unbalanced from %p\n", irq,
553 __builtin_return_address(0));
554 }
555 spin_unlock_irqrestore(&desc->lock, flags);
556}
557
558
559
560
561
562
563asmlinkage unsigned int do_IRQ(struct pt_regs regs)
564{
565
566
567
568
569
570
571
572
573
574
575 int irq = regs.orig_eax & 0xff;
576 int cpu = smp_processor_id();
577 irq_desc_t *desc = irq_desc + irq;
578 struct irqaction * action;
579 unsigned int status;
580#ifdef CONFIG_DEBUG_STACKOVERFLOW
581 long esp;
582
583
584 __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191));
585 if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
586 extern void show_stack(unsigned long *);
587
588 printk("do_IRQ: stack overflow: %ld\n",
589 esp - sizeof(struct task_struct));
590 __asm__ __volatile__("movl %%esp,%0" : "=r" (esp));
591 show_stack((void *)esp);
592 }
593#endif
594
595 kstat.irqs[cpu][irq]++;
596 spin_lock(&desc->lock);
597 desc->handler->ack(irq);
598
599
600
601
602 status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
603 status |= IRQ_PENDING;
604
605
606
607
608
609 action = NULL;
610 if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
611 action = desc->action;
612 status &= ~IRQ_PENDING;
613 status |= IRQ_INPROGRESS;
614 }
615 desc->status = status;
616
617
618
619
620
621
622
623 if (!action)
624 goto out;
625
626
627
628
629
630
631
632
633
634
635
636 for (;;) {
637 spin_unlock(&desc->lock);
638 handle_IRQ_event(irq, ®s, action);
639 spin_lock(&desc->lock);
640
641 if (!(desc->status & IRQ_PENDING))
642 break;
643 desc->status &= ~IRQ_PENDING;
644 }
645 desc->status &= ~IRQ_INPROGRESS;
646out:
647
648
649
650
651 desc->handler->end(irq);
652 spin_unlock(&desc->lock);
653
654 if (softirq_pending(cpu))
655 do_softirq();
656 return 1;
657}
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691int request_irq(unsigned int irq,
692 void (*handler)(int, void *, struct pt_regs *),
693 unsigned long irqflags,
694 const char * devname,
695 void *dev_id)
696{
697 int retval;
698 struct irqaction * action;
699
700#if 1
701
702
703
704
705
706
707 if (irqflags & SA_SHIRQ) {
708 if (!dev_id)
709 printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
710 }
711#endif
712
713 if (irq >= NR_IRQS)
714 return -EINVAL;
715 if (!handler)
716 return -EINVAL;
717
718 action = (struct irqaction *)
719 kmalloc(sizeof(struct irqaction), GFP_KERNEL);
720 if (!action)
721 return -ENOMEM;
722
723 action->handler = handler;
724 action->flags = irqflags;
725 action->mask = 0;
726 action->name = devname;
727 action->next = NULL;
728 action->dev_id = dev_id;
729
730 retval = setup_irq(irq, action);
731 if (retval)
732 kfree(action);
733 return retval;
734}
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754void free_irq(unsigned int irq, void *dev_id)
755{
756 irq_desc_t *desc;
757 struct irqaction **p;
758 unsigned long flags;
759
760 if (irq >= NR_IRQS)
761 return;
762
763 desc = irq_desc + irq;
764 spin_lock_irqsave(&desc->lock,flags);
765 p = &desc->action;
766 for (;;) {
767 struct irqaction * action = *p;
768 if (action) {
769 struct irqaction **pp = p;
770 p = &action->next;
771 if (action->dev_id != dev_id)
772 continue;
773
774
775 *pp = action->next;
776 if (!desc->action) {
777 desc->status |= IRQ_DISABLED;
778 desc->handler->shutdown(irq);
779 }
780 spin_unlock_irqrestore(&desc->lock,flags);
781
782#ifdef CONFIG_SMP
783
784 while (desc->status & IRQ_INPROGRESS) {
785 barrier();
786 cpu_relax();
787 }
788#endif
789 kfree(action);
790 return;
791 }
792 printk("Trying to free free IRQ%d\n",irq);
793 spin_unlock_irqrestore(&desc->lock,flags);
794 return;
795 }
796}
797
798
799
800
801
802
803
804
805
806
807static DECLARE_MUTEX(probe_sem);
808
809
810
811
812
813
814
815
816
817unsigned long probe_irq_on(void)
818{
819 unsigned int i;
820 irq_desc_t *desc;
821 unsigned long val;
822 unsigned long delay;
823
824 down(&probe_sem);
825
826
827
828
829 for (i = NR_IRQS-1; i > 0; i--) {
830 desc = irq_desc + i;
831
832 spin_lock_irq(&desc->lock);
833 if (!irq_desc[i].action)
834 irq_desc[i].handler->startup(i);
835 spin_unlock_irq(&desc->lock);
836 }
837
838
839 for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
840 synchronize_irq();
841
842
843
844
845
846
847 for (i = NR_IRQS-1; i > 0; i--) {
848 desc = irq_desc + i;
849
850 spin_lock_irq(&desc->lock);
851 if (!desc->action) {
852 desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
853 if (desc->handler->startup(i))
854 desc->status |= IRQ_PENDING;
855 }
856 spin_unlock_irq(&desc->lock);
857 }
858
859
860
861
862 for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
863 synchronize_irq();
864
865
866
867
868 val = 0;
869 for (i = 0; i < NR_IRQS; i++) {
870 irq_desc_t *desc = irq_desc + i;
871 unsigned int status;
872
873 spin_lock_irq(&desc->lock);
874 status = desc->status;
875
876 if (status & IRQ_AUTODETECT) {
877
878 if (!(status & IRQ_WAITING)) {
879 desc->status = status & ~IRQ_AUTODETECT;
880 desc->handler->shutdown(i);
881 } else
882 if (i < 32)
883 val |= 1 << i;
884 }
885 spin_unlock_irq(&desc->lock);
886 }
887
888 return val;
889}
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908unsigned int probe_irq_mask(unsigned long val)
909{
910 int i;
911 unsigned int mask;
912
913 mask = 0;
914 for (i = 0; i < NR_IRQS; i++) {
915 irq_desc_t *desc = irq_desc + i;
916 unsigned int status;
917
918 spin_lock_irq(&desc->lock);
919 status = desc->status;
920
921 if (status & IRQ_AUTODETECT) {
922 if (i < 16 && !(status & IRQ_WAITING))
923 mask |= 1 << i;
924
925 desc->status = status & ~IRQ_AUTODETECT;
926 desc->handler->shutdown(i);
927 }
928 spin_unlock_irq(&desc->lock);
929 }
930 up(&probe_sem);
931
932 return mask & val;
933}
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958int probe_irq_off(unsigned long val)
959{
960 int i, irq_found, nr_irqs;
961
962 nr_irqs = 0;
963 irq_found = 0;
964 for (i = 0; i < NR_IRQS; i++) {
965 irq_desc_t *desc = irq_desc + i;
966 unsigned int status;
967
968 spin_lock_irq(&desc->lock);
969 status = desc->status;
970
971 if (status & IRQ_AUTODETECT) {
972 if (!(status & IRQ_WAITING)) {
973 if (!nr_irqs)
974 irq_found = i;
975 nr_irqs++;
976 }
977 desc->status = status & ~IRQ_AUTODETECT;
978 desc->handler->shutdown(i);
979 }
980 spin_unlock_irq(&desc->lock);
981 }
982 up(&probe_sem);
983
984 if (nr_irqs > 1)
985 irq_found = -irq_found;
986 return irq_found;
987}
988
989
990int setup_irq(unsigned int irq, struct irqaction * new)
991{
992 int shared = 0;
993 unsigned long flags;
994 struct irqaction *old, **p;
995 irq_desc_t *desc = irq_desc + irq;
996
997
998
999
1000
1001
1002 if (new->flags & SA_SAMPLE_RANDOM) {
1003
1004
1005
1006
1007
1008
1009
1010
1011 rand_initialize_irq(irq);
1012 }
1013
1014
1015
1016
1017 spin_lock_irqsave(&desc->lock,flags);
1018 p = &desc->action;
1019 if ((old = *p) != NULL) {
1020
1021 if (!(old->flags & new->flags & SA_SHIRQ)) {
1022 spin_unlock_irqrestore(&desc->lock,flags);
1023 return -EBUSY;
1024 }
1025
1026
1027 do {
1028 p = &old->next;
1029 old = *p;
1030 } while (old);
1031 shared = 1;
1032 }
1033
1034 *p = new;
1035
1036 if (!shared) {
1037 desc->depth = 0;
1038 desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
1039 desc->handler->startup(irq);
1040 }
1041 spin_unlock_irqrestore(&desc->lock,flags);
1042
1043 register_irq_proc(irq);
1044 return 0;
1045}
1046
1047static struct proc_dir_entry * root_irq_dir;
1048static struct proc_dir_entry * irq_dir [NR_IRQS];
1049
1050#define HEX_DIGITS 8
1051
1052static unsigned int parse_hex_value (const char *buffer,
1053 unsigned long count, unsigned long *ret)
1054{
1055 unsigned char hexnum [HEX_DIGITS];
1056 unsigned long value;
1057 int i;
1058
1059 if (!count)
1060 return -EINVAL;
1061 if (count > HEX_DIGITS)
1062 count = HEX_DIGITS;
1063 if (copy_from_user(hexnum, buffer, count))
1064 return -EFAULT;
1065
1066
1067
1068
1069
1070 value = 0;
1071
1072 for (i = 0; i < count; i++) {
1073 unsigned int c = hexnum[i];
1074
1075 switch (c) {
1076 case '0' ... '9': c -= '0'; break;
1077 case 'a' ... 'f': c -= 'a'-10; break;
1078 case 'A' ... 'F': c -= 'A'-10; break;
1079 default:
1080 goto out;
1081 }
1082 value = (value << 4) | c;
1083 }
1084out:
1085 *ret = value;
1086 return 0;
1087}
1088
1089#if CONFIG_SMP
1090
1091static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
1092
1093static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
1094static int irq_affinity_read_proc (char *page, char **start, off_t off,
1095 int count, int *eof, void *data)
1096{
1097 if (count < HEX_DIGITS+1)
1098 return -EINVAL;
1099 return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
1100}
1101
1102static int irq_affinity_write_proc (struct file *file, const char *buffer,
1103 unsigned long count, void *data)
1104{
1105 int irq = (long) data, full_count = count, err;
1106 unsigned long new_value;
1107
1108 if (!irq_desc[irq].handler->set_affinity)
1109 return -EIO;
1110
1111 err = parse_hex_value(buffer, count, &new_value);
1112
1113
1114
1115
1116
1117
1118 if (!(new_value & cpu_online_map))
1119 return -EINVAL;
1120
1121 irq_affinity[irq] = new_value;
1122 irq_desc[irq].handler->set_affinity(irq, new_value);
1123
1124 return full_count;
1125}
1126
1127#endif
1128
1129static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
1130 int count, int *eof, void *data)
1131{
1132 unsigned long *mask = (unsigned long *) data;
1133 if (count < HEX_DIGITS+1)
1134 return -EINVAL;
1135 return sprintf (page, "%08lx\n", *mask);
1136}
1137
1138static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
1139 unsigned long count, void *data)
1140{
1141 unsigned long *mask = (unsigned long *) data, full_count = count, err;
1142 unsigned long new_value;
1143
1144 err = parse_hex_value(buffer, count, &new_value);
1145 if (err)
1146 return err;
1147
1148 *mask = new_value;
1149 return full_count;
1150}
1151
1152#define MAX_NAMELEN 10
1153
1154static void register_irq_proc (unsigned int irq)
1155{
1156 char name [MAX_NAMELEN];
1157
1158 if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
1159 irq_dir[irq])
1160 return;
1161
1162 memset(name, 0, MAX_NAMELEN);
1163 sprintf(name, "%d", irq);
1164
1165
1166 irq_dir[irq] = proc_mkdir(name, root_irq_dir);
1167
1168#if CONFIG_SMP
1169 {
1170 struct proc_dir_entry *entry;
1171
1172
1173 entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
1174
1175 if (entry) {
1176 entry->nlink = 1;
1177 entry->data = (void *)(long)irq;
1178 entry->read_proc = irq_affinity_read_proc;
1179 entry->write_proc = irq_affinity_write_proc;
1180 }
1181
1182 smp_affinity_entry[irq] = entry;
1183 }
1184#endif
1185}
1186
1187unsigned long prof_cpu_mask = -1;
1188
1189void init_irq_proc (void)
1190{
1191 struct proc_dir_entry *entry;
1192 int i;
1193
1194
1195 root_irq_dir = proc_mkdir("irq", 0);
1196
1197
1198 entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
1199
1200 if (!entry)
1201 return;
1202
1203 entry->nlink = 1;
1204 entry->data = (void *)&prof_cpu_mask;
1205 entry->read_proc = prof_cpu_mask_read_proc;
1206 entry->write_proc = prof_cpu_mask_write_proc;
1207
1208
1209
1210
1211 for (i = 0; i < NR_IRQS; i++)
1212 register_irq_proc(i);
1213}
1214
1215