2 * linux/arch/ppc/amiga/ints.c
4 * Linux/m68k general interrupt handling code from arch/m68k/kernel/ints.c
5 * Needed to drive the m68k emulating IRQ hardware on the PowerUp boards.
8 #include <linux/types.h>
9 #include <linux/sched.h>
10 #include <linux/kernel_stat.h>
11 #include <linux/errno.h>
12 #include <linux/init.h>
14 #include <asm/setup.h>
15 #include <asm/system.h>
17 #include <asm/traps.h>
19 #include <asm/machdep.h>
21 /* table for system interrupt handlers */
22 static irq_handler_t irq_list
[SYS_IRQS
];
24 static const char *default_names
[SYS_IRQS
] = {
25 "spurious int", "int1 handler", "int2 handler", "int3 handler",
26 "int4 handler", "int5 handler", "int6 handler", "int7 handler"
29 /* The number of spurious interrupts */
30 volatile unsigned int num_spurious
;
32 #define NUM_IRQ_NODES 100
33 static irq_node_t nodes
[NUM_IRQ_NODES
];
43 * This function should be called during kernel startup to initialize
44 * the IRQ handling routines.
48 void m68k_init_IRQ(void)
52 for (i
= 0; i
< SYS_IRQS
; i
++) {
53 if (mach_default_handler
)
54 irq_list
[i
].handler
= (*mach_default_handler
)[i
];
55 irq_list
[i
].flags
= 0;
56 irq_list
[i
].dev_id
= NULL
;
57 irq_list
[i
].devname
= default_names
[i
];
60 for (i
= 0; i
< NUM_IRQ_NODES
; i
++)
61 nodes
[i
].handler
= NULL
;
66 irq_node_t
*new_irq_node(void)
71 for (node
= nodes
, i
= NUM_IRQ_NODES
-1; i
>= 0; node
++, i
--)
75 printk ("new_irq_node: out of nodes\n");
79 int sys_request_irq(unsigned int irq
,
80 void (*handler
)(int, void *, struct pt_regs
*),
81 unsigned long flags
, const char *devname
, void *dev_id
)
83 if (irq
< IRQ1
|| irq
> IRQ7
) {
84 printk("%s: Incorrect IRQ %d from %s\n",
85 __FUNCTION__
, irq
, devname
);
90 if (!(irq_list
[irq
].flags
& IRQ_FLG_STD
)) {
91 if (irq_list
[irq
].flags
& IRQ_FLG_LOCK
) {
92 printk("%s: IRQ %d from %s is not replaceable\n",
93 __FUNCTION__
, irq
, irq_list
[irq
].devname
);
96 if (!(flags
& IRQ_FLG_REPLACE
)) {
97 printk("%s: %s can't replace IRQ %d from %s\n",
98 __FUNCTION__
, devname
, irq
, irq_list
[irq
].devname
);
104 irq_list
[irq
].handler
= handler
;
105 irq_list
[irq
].flags
= flags
;
106 irq_list
[irq
].dev_id
= dev_id
;
107 irq_list
[irq
].devname
= devname
;
111 void sys_free_irq(unsigned int irq
, void *dev_id
)
113 if (irq
< IRQ1
|| irq
> IRQ7
) {
114 printk("%s: Incorrect IRQ %d\n", __FUNCTION__
, irq
);
118 if (irq_list
[irq
].dev_id
!= dev_id
)
119 printk("%s: Removing probably wrong IRQ %d from %s\n",
120 __FUNCTION__
, irq
, irq_list
[irq
].devname
);
122 irq_list
[irq
].handler
= (*mach_default_handler
)[irq
];
123 irq_list
[irq
].flags
= 0;
124 irq_list
[irq
].dev_id
= NULL
;
125 irq_list
[irq
].devname
= default_names
[irq
];
128 asmlinkage
void process_int(unsigned long vec
, struct pt_regs
*fp
)
130 if (vec
>= VEC_INT1
&& vec
<= VEC_INT7
&& !MACH_IS_BVME6000
) {
132 kstat
.irqs
[0][vec
]++;
133 irq_list
[vec
].handler(vec
, irq_list
[vec
].dev_id
, fp
);
135 if (mach_process_int
)
136 mach_process_int(vec
, fp
);
138 panic("Can't process interrupt vector %ld\n", vec
);
143 int m68k_get_irq_list(char *buf
)
147 /* autovector interrupts */
148 if (mach_default_handler
) {
149 for (i
= 0; i
< SYS_IRQS
; i
++) {
150 len
+= sprintf(buf
+len
, "auto %2d: %10u ", i
,
151 i
? kstat
.irqs
[0][i
] : num_spurious
);
152 len
+= sprintf(buf
+len
, " ");
153 len
+= sprintf(buf
+len
, "%s\n", irq_list
[i
].devname
);
157 len
+= mach_get_irq_list(buf
+len
);