1/* $Id: irq.c,v 1.1.1.1 2008/10/15 03:26:01 james26_jang Exp $
2 *
3 *	linux/arch/cris/kernel/irq.c
4 *
5 *      Copyright (c) 2000,2001 Axis Communications AB
6 *
7 *      Authors: Bjorn Wesen (bjornw@axis.com)
8 *
9 * This file contains the code used by various IRQ handling routines:
10 * asking for different IRQ's should be done through these routines
11 * instead of just grabbing them. Thus setups with different IRQ numbers
12 * shouldn't result in any weird surprises, and installing new handlers
13 * should be easier.
14 *
15 * Notice Linux/CRIS: these routines do not care about SMP
16 *
17 */
18
19/*
20 * IRQ's are in fact implemented a bit like signal handlers for the kernel.
21 * Naturally it's not a 1:1 relation, but there are similarities.
22 */
23
24#include <linux/config.h>
25#include <linux/ptrace.h>
26#include <linux/errno.h>
27#include <linux/kernel_stat.h>
28#include <linux/signal.h>
29#include <linux/sched.h>
30#include <linux/ioport.h>
31#include <linux/interrupt.h>
32#include <linux/timex.h>
33#include <linux/slab.h>
34#include <linux/random.h>
35#include <linux/init.h>
36
37#include <asm/system.h>
38#include <asm/io.h>
39#include <asm/irq.h>
40#include <asm/bitops.h>
41
42#include <asm/svinto.h>
43
44char *hw_bp_msg = "BP 0x%x\n";
45
46static inline void
47mask_irq(unsigned int irq_nr)
48{
49	*R_VECT_MASK_CLR = 1 << irq_nr;
50}
51
52static inline void
53unmask_irq(unsigned int irq_nr)
54{
55	*R_VECT_MASK_SET = 1 << irq_nr;
56}
57
58void
59disable_irq(unsigned int irq_nr)
60{
61	unsigned long flags;
62
63	save_flags(flags);
64	cli();
65	mask_irq(irq_nr);
66	restore_flags(flags);
67}
68
69void
70enable_irq(unsigned int irq_nr)
71{
72	unsigned long flags;
73	save_flags(flags);
74	cli();
75	unmask_irq(irq_nr);
76	restore_flags(flags);
77}
78
79unsigned long
80probe_irq_on()
81{
82	return 0;
83}
84
85int
86probe_irq_off(unsigned long x)
87{
88	return 0;
89}
90
91irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */
92
93/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
94 * global just so that the kernel gdb can use it.
95 */
96
97void
98set_int_vector(int n, irqvectptr addr, irqvectptr saddr)
99{
100	/* remember the shortcut entry point, after the prologue */
101
102	irq_shortcuts[n] = saddr;
103
104	etrax_irv->v[n + 0x20] = (irqvectptr)addr;
105}
106
107/* the breakpoint vector is obviously not made just like the normal irq handlers
108 * but needs to contain _code_ to jump to addr.
109 *
110 * the BREAK n instruction jumps to IBR + n * 8
111 */
112
113void
114set_break_vector(int n, irqvectptr addr)
115{
116	unsigned short *jinstr = (unsigned short *)&etrax_irv->v[n*2];
117	unsigned long *jaddr = (unsigned long *)(jinstr + 1);
118
119	/* if you don't know what this does, do not touch it! */
120
121	*jinstr = 0x0d3f;
122	*jaddr = (unsigned long)addr;
123
124	/* 00000026 <clrlop+1a> 3f0d82000000     jump  0x82 */
125}
126
127
128/*
129 * This builds up the IRQ handler stubs using some ugly macros in irq.h
130 *
131 * These macros create the low-level assembly IRQ routines that do all
132 * the operations that are needed. They are also written to be fast - and to
133 * disable interrupts as little as humanly possible.
134 *
135 */
136
137/* IRQ0 and 1 are special traps */
138void hwbreakpoint(void);
139void IRQ1_interrupt(void);
140BUILD_TIMER_IRQ(2, 0x04)       /* the timer interrupt is somewhat special */
141BUILD_IRQ(3, 0x08)
142BUILD_IRQ(4, 0x10)
143BUILD_IRQ(5, 0x20)
144BUILD_IRQ(6, 0x40)
145BUILD_IRQ(7, 0x80)
146BUILD_IRQ(8, 0x100)
147BUILD_IRQ(9, 0x200)
148BUILD_IRQ(10, 0x400)
149BUILD_IRQ(11, 0x800)
150BUILD_IRQ(12, 0x1000)
151BUILD_IRQ(13, 0x2000)
152void mmu_bus_fault(void);      /* IRQ 14 is the bus fault interrupt */
153void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
154BUILD_IRQ(16, 0x10000)
155BUILD_IRQ(17, 0x20000)
156BUILD_IRQ(18, 0x40000)
157BUILD_IRQ(19, 0x80000)
158BUILD_IRQ(20, 0x100000)
159BUILD_IRQ(21, 0x200000)
160BUILD_IRQ(22, 0x400000)
161BUILD_IRQ(23, 0x800000)
162BUILD_IRQ(24, 0x1000000)
163BUILD_IRQ(25, 0x2000000)
164/* IRQ 26-30 are reserved */
165BUILD_IRQ(31, 0x80000000)
166
167/*
168 * Pointers to the low-level handlers
169 */
170
171static void (*interrupt[NR_IRQS])(void) = {
172	NULL, NULL, IRQ2_interrupt, IRQ3_interrupt,
173	IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
174	IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
175	IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,
176	IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,
177	IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,
178	IRQ24_interrupt, IRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
179	IRQ31_interrupt
180};
181
182static void (*sinterrupt[NR_IRQS])(void) = {
183	NULL, NULL, sIRQ2_interrupt, sIRQ3_interrupt,
184	sIRQ4_interrupt, sIRQ5_interrupt, sIRQ6_interrupt, sIRQ7_interrupt,
185	sIRQ8_interrupt, sIRQ9_interrupt, sIRQ10_interrupt, sIRQ11_interrupt,
186	sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL,
187	sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt,
188	sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt,
189	sIRQ24_interrupt, sIRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
190	sIRQ31_interrupt
191};
192
193static void (*bad_interrupt[NR_IRQS])(void) = {
194        NULL, NULL,
195	NULL, bad_IRQ3_interrupt,
196	bad_IRQ4_interrupt, bad_IRQ5_interrupt,
197	bad_IRQ6_interrupt, bad_IRQ7_interrupt,
198	bad_IRQ8_interrupt, bad_IRQ9_interrupt,
199	bad_IRQ10_interrupt, bad_IRQ11_interrupt,
200	bad_IRQ12_interrupt, bad_IRQ13_interrupt,
201	NULL, NULL,
202	bad_IRQ16_interrupt, bad_IRQ17_interrupt,
203	bad_IRQ18_interrupt, bad_IRQ19_interrupt,
204	bad_IRQ20_interrupt, bad_IRQ21_interrupt,
205	bad_IRQ22_interrupt, bad_IRQ23_interrupt,
206	bad_IRQ24_interrupt, bad_IRQ25_interrupt,
207	NULL, NULL, NULL, NULL, NULL,
208	bad_IRQ31_interrupt
209};
210
211/*
212 * Initial irq handlers.
213 */
214
215static struct irqaction *irq_action[NR_IRQS] = {
216	NULL, NULL, NULL, NULL,
217	NULL, NULL, NULL, NULL,
218	NULL, NULL, NULL, NULL,
219	NULL, NULL, NULL, NULL,
220	NULL, NULL, NULL, NULL,
221	NULL, NULL, NULL, NULL,
222	NULL, NULL, NULL, NULL,
223	NULL, NULL, NULL, NULL
224};
225
226int get_irq_list(char *buf)
227{
228	int i, len = 0;
229	struct irqaction * action;
230
231	for (i = 0; i < NR_IRQS; i++) {
232		action = irq_action[i];
233		if (!action)
234			continue;
235		len += sprintf(buf+len, "%2d: %10u %c %s",
236			i, kstat.irqs[0][i],
237			(action->flags & SA_INTERRUPT) ? '+' : ' ',
238			action->name);
239		for (action = action->next; action; action = action->next) {
240			len += sprintf(buf+len, ",%s %s",
241				(action->flags & SA_INTERRUPT) ? " +" : "",
242				action->name);
243		}
244		len += sprintf(buf+len, "\n");
245	}
246	return len;
247}
248
249/* called by the assembler IRQ entry functions defined in irq.h
250 * to dispatch the interrupts to registred handlers
251 * interrupts are disabled upon entry - depending on if the
252 * interrupt was registred with SA_INTERRUPT or not, interrupts
253 * are re-enabled or not.
254 */
255
256asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
257{
258	struct irqaction *action;
259	int do_random, cpu;
260
261        cpu = smp_processor_id();
262        irq_enter(cpu);
263	kstat.irqs[cpu][irq]++;
264
265	action = irq_action[irq];
266        if (action) {
267                if (!(action->flags & SA_INTERRUPT))
268                        __sti();
269                action = irq_action[irq];
270                do_random = 0;
271                do {
272                        do_random |= action->flags;
273                        action->handler(irq, action->dev_id, regs);
274                        action = action->next;
275                } while (action);
276                if (do_random & SA_SAMPLE_RANDOM)
277                        add_interrupt_randomness(irq);
278                __cli();
279        }
280        irq_exit(cpu);
281
282	if (softirq_pending(cpu))
283                do_softirq();
284
285        /* unmasking and bottom half handling is done magically for us. */
286}
287
288/* this function links in a handler into the chain of handlers for the
289   given irq, and if the irq has never been registred, the appropriate
290   handler is entered into the interrupt vector
291*/
292
293int setup_etrax_irq(int irq, struct irqaction * new)
294{
295	int shared = 0;
296	struct irqaction *old, **p;
297	unsigned long flags;
298
299	p = irq_action + irq;
300	if ((old = *p) != NULL) {
301		/* Can't share interrupts unless both agree to */
302		if (!(old->flags & new->flags & SA_SHIRQ))
303			return -EBUSY;
304
305		/* Can't share interrupts unless both are same type */
306		if ((old->flags ^ new->flags) & SA_INTERRUPT)
307			return -EBUSY;
308
309		/* add new interrupt at end of irq queue */
310		do {
311			p = &old->next;
312			old = *p;
313		} while (old);
314		shared = 1;
315	}
316
317	if (new->flags & SA_SAMPLE_RANDOM)
318		rand_initialize_irq(irq);
319
320	save_flags(flags);
321	cli();
322	*p = new;
323
324	if (!shared) {
325		/* if the irq wasn't registred before, enter it into the vector table
326		   and unmask it physically
327		*/
328		set_int_vector(irq, interrupt[irq], sinterrupt[irq]);
329		unmask_irq(irq);
330	}
331
332	restore_flags(flags);
333	return 0;
334}
335
336/* this function is called by a driver to register an irq handler
337   Valid flags:
338   SA_INTERRUPT -> it's a fast interrupt, handler called with irq disabled and
339                   no signal checking etc is performed upon exit
340   SA_SHIRQ -> the interrupt can be shared between different handlers, the handler
341                is required to check if the irq was "aimed" at it explicitely
342   SA_RANDOM -> the interrupt will add to the random generators entropy
343*/
344
345int request_irq(unsigned int irq,
346		void (*handler)(int, void *, struct pt_regs *),
347		unsigned long irqflags,
348		const char * devname,
349		void *dev_id)
350{
351	int retval;
352	struct irqaction * action;
353
354	/* interrupts 0 and 1 are hardware breakpoint and NMI and we can't support
355	   these yet. interrupt 15 is the multiple irq, it's special. */
356
357	if(irq < 2 || irq == 15 || irq >= NR_IRQS)
358		return -EINVAL;
359
360	if(!handler)
361		return -EINVAL;
362
363	/* allocate and fill in a handler structure and setup the irq */
364
365	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
366	if (!action)
367		return -ENOMEM;
368
369	action->handler = handler;
370	action->flags = irqflags;
371	action->mask = 0;
372	action->name = devname;
373	action->next = NULL;
374	action->dev_id = dev_id;
375
376	retval = setup_etrax_irq(irq, action);
377
378	if (retval)
379		kfree(action);
380	return retval;
381}
382
383void free_irq(unsigned int irq, void *dev_id)
384{
385	struct irqaction * action, **p;
386	unsigned long flags;
387
388	if (irq >= NR_IRQS) {
389		printk("Trying to free IRQ%d\n",irq);
390		return;
391	}
392	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
393		if (action->dev_id != dev_id)
394			continue;
395
396		/* Found it - now free it */
397		save_flags(flags);
398		cli();
399		*p = action->next;
400		if (!irq_action[irq]) {
401			mask_irq(irq);
402			set_int_vector(irq, bad_interrupt[irq], 0);
403		}
404		restore_flags(flags);
405		kfree(action);
406		return;
407	}
408	printk("Trying to free free IRQ%d\n",irq);
409}
410
411void weird_irq(void)
412{
413	__asm__("di");
414	printk("weird irq\n");
415	while(1);
416}
417
418/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
419   setting the irq vector table to point to bad_interrupt ptrs.
420*/
421
422void system_call(void);  /* from entry.S */
423void do_sigtrap(void); /* from entry.S */
424void gdb_handle_breakpoint(void); /* from entry.S */
425
426void __init
427init_IRQ(void)
428{
429	int i;
430
431	/* clear all interrupt masks */
432
433#ifndef CONFIG_SVINTO_SIM
434	*R_IRQ_MASK0_CLR = 0xffffffff;
435	*R_IRQ_MASK1_CLR = 0xffffffff;
436	*R_IRQ_MASK2_CLR = 0xffffffff;
437#endif
438
439	*R_VECT_MASK_CLR = 0xffffffff;
440
441	/* clear the shortcut entry points */
442
443	for(i = 0; i < NR_IRQS; i++)
444		irq_shortcuts[i] = NULL;
445
446        for (i = 0; i < 256; i++)
447               etrax_irv->v[i] = weird_irq;
448
449        /* the entries in the break vector contain actual code to be
450           executed by the associated break handler, rather than just a jump
451           address. therefore we need to setup a default breakpoint handler
452           for all breakpoints */
453
454	for (i = 0; i < 16; i++)
455                set_break_vector(i, do_sigtrap);
456
457	/* set all etrax irq's to the bad handlers */
458	for (i = 2; i < NR_IRQS; i++)
459		set_int_vector(i, bad_interrupt[i], 0);
460
461	/* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
462
463	set_int_vector(15, multiple_interrupt, 0);
464
465	/* 0 and 1 which are special breakpoint/NMI traps */
466
467	set_int_vector(0, hwbreakpoint, 0);
468	set_int_vector(1, IRQ1_interrupt, 0);
469
470	/* and irq 14 which is the mmu bus fault handler */
471
472	set_int_vector(14, mmu_bus_fault, 0);
473
474	/* setup the system-call trap, which is reached by BREAK 13 */
475
476	set_break_vector(13, system_call);
477
478        /* setup a breakpoint handler for debugging used for both user and
479           kernel mode debugging  (which is why it is not inside an ifdef
480           CONFIG_ETRAX_KGDB) */
481        set_break_vector(8, gdb_handle_breakpoint);
482
483#ifdef CONFIG_ETRAX_KGDB
484	/* setup kgdb if its enabled, and break into the debugger */
485	kgdb_init();
486	breakpoint();
487#endif
488
489}
490
491#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
492/* Used by other archs to show/control IRQ steering during SMP */
493void __init
494init_irq_proc(void)
495{
496}
497#endif
498