1 /*
2  * arch/m68k/mvme16x/16xints.c
3  *
4  * Copyright (C) 1995 Richard Hirst [richard@sleepie.demon.co.uk]
5  *
6  * based on amiints.c -- Amiga Linux interrupt handling code
7  *
8  * This file is subject to the terms and conditions of the GNU General Public
9  * License.  See the file README.legal in the main directory of this archive
10  * for more details.
11  *
12  */
13 
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 
18 #include <asm/system.h>
19 #include <asm/ptrace.h>
20 #include <asm/irq.h>
21 
22 static void mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp);
23 
24 /*
25  * This should ideally be 4 elements only, for speed.
26  */
27 
28 static struct {
29 	void		(*handler)(int, void *, struct pt_regs *);
30 	unsigned long	flags;
31 	void		*dev_id;
32 	const char	*devname;
33 	unsigned	count;
34 } irq_tab[192];
35 
36 /*
37  * void mvme16x_init_IRQ (void)
38  *
39  * Parameters:	None
40  *
41  * Returns:	Nothing
42  *
43  * This function is called during kernel startup to initialize
44  * the mvme16x IRQ handling routines.  Should probably ensure
45  * that the base vectors for the VMEChip2 and PCCChip2 are valid.
46  */
47 
mvme16x_init_IRQ(void)48 void mvme16x_init_IRQ (void)
49 {
50 	int i;
51 
52 	for (i = 0; i < 192; i++) {
53 		irq_tab[i].handler = mvme16x_defhand;
54 		irq_tab[i].flags = IRQ_FLG_STD;
55 		irq_tab[i].dev_id = NULL;
56 		irq_tab[i].devname = NULL;
57 		irq_tab[i].count = 0;
58 	}
59 }
60 
mvme16x_request_irq(unsigned int irq,void (* handler)(int,void *,struct pt_regs *),unsigned long flags,const char * devname,void * dev_id)61 int mvme16x_request_irq(unsigned int irq,
62 		void (*handler)(int, void *, struct pt_regs *),
63                 unsigned long flags, const char *devname, void *dev_id)
64 {
65 	if (irq < 64 || irq > 255) {
66 		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
67 		return -ENXIO;
68 	}
69 
70 	if (!(irq_tab[irq-64].flags & IRQ_FLG_STD)) {
71 		if (irq_tab[irq-64].flags & IRQ_FLG_LOCK) {
72 			printk("%s: IRQ %d from %s is not replaceable\n",
73 			       __FUNCTION__, irq, irq_tab[irq-64].devname);
74 			return -EBUSY;
75 		}
76 		if (flags & IRQ_FLG_REPLACE) {
77 			printk("%s: %s can't replace IRQ %d from %s\n",
78 			       __FUNCTION__, devname, irq, irq_tab[irq-64].devname);
79 			return -EBUSY;
80 		}
81 	}
82 	irq_tab[irq-64].handler = handler;
83 	irq_tab[irq-64].flags   = flags;
84 	irq_tab[irq-64].dev_id  = dev_id;
85 	irq_tab[irq-64].devname = devname;
86 	return 0;
87 }
88 
mvme16x_free_irq(unsigned int irq,void * dev_id)89 void mvme16x_free_irq(unsigned int irq, void *dev_id)
90 {
91 	if (irq < 64 || irq > 255) {
92 		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
93 		return;
94 	}
95 
96 	if (irq_tab[irq-64].dev_id != dev_id)
97 		printk("%s: Removing probably wrong IRQ %d from %s\n",
98 		       __FUNCTION__, irq, irq_tab[irq-64].devname);
99 
100 	irq_tab[irq-64].handler = mvme16x_defhand;;
101 	irq_tab[irq-64].flags   = IRQ_FLG_STD;
102 	irq_tab[irq-64].dev_id  = NULL;
103 	irq_tab[irq-64].devname = NULL;
104 }
105 
mvme16x_process_int(unsigned long vec,struct pt_regs * fp)106 void mvme16x_process_int (unsigned long vec, struct pt_regs *fp)
107 {
108 	if (vec < 64 || vec > 255)
109 		printk ("mvme16x_process_int: Illegal vector %ld", vec);
110 	else
111 	{
112 		irq_tab[vec-64].count++;
113 		irq_tab[vec-64].handler(vec, irq_tab[vec-64].dev_id, fp);
114 	}
115 }
116 
mvme16x_get_irq_list(char * buf)117 int mvme16x_get_irq_list (char *buf)
118 {
119 	int i, len = 0;
120 
121 	for (i = 0; i < 192; i++) {
122 		if (irq_tab[i].count)
123 			len += sprintf (buf+len, "Vec 0x%02x: %8d  %s\n",
124 			    i+64, irq_tab[i].count,
125 			    irq_tab[i].devname ? irq_tab[i].devname : "free");
126 	}
127 	return len;
128 }
129 
130 
mvme16x_defhand(int irq,void * dev_id,struct pt_regs * fp)131 static void mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp)
132 {
133 	printk ("Unknown interrupt 0x%02x\n", irq);
134 }
135 
136 
mvme16x_enable_irq(unsigned int irq)137 void mvme16x_enable_irq (unsigned int irq)
138 {
139 }
140 
141 
mvme16x_disable_irq(unsigned int irq)142 void mvme16x_disable_irq (unsigned int irq)
143 {
144 }
145 
146 
147