intr.c revision 147166
1/*	$NetBSD: intr.c,v 1.12 2003/07/15 00:24:41 lukem Exp $	*/
2
3/*-
4 * Copyright (c) 2004 Olivier Houchard.
5 * Copyright (c) 1994-1998 Mark Brinicombe.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by Mark Brinicombe
19 *	for the NetBSD Project.
20 * 4. The name of the company nor the name of the author may be used to
21 *    endorse or promote products derived from this software without specific
22 *    prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * Soft interrupt and other generic interrupt functions.
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: head/sys/arm/arm/intr.c 147166 2005-06-09 12:26:20Z cognet $");
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/syslog.h>
44#include <sys/malloc.h>
45#include <sys/proc.h>
46#include <sys/bus.h>
47#include <sys/interrupt.h>
48#include <sys/conf.h>
49#include <machine/atomic.h>
50#include <machine/intr.h>
51#include <machine/cpu.h>
52
53static struct ithd *ithreads[NIRQ];
54static int intrcnt_tab[NIRQ];
55static int intrcnt_index = 0;
56static int last_printed = 0;
57
58void	arm_handler_execute(void *, int);
59
60void
61arm_setup_irqhandler(const char *name, void (*hand)(void*), void *arg,
62    int irq, int flags, void **cookiep)
63{
64	struct ithd *cur_ith;
65	int error;
66
67	if (irq < 0 || irq >= NIRQ)
68		return;
69	cur_ith = ithreads[irq];
70	if (cur_ith == NULL) {
71		error = ithread_create(&cur_ith, irq, 0, arm_mask_irq,
72		    arm_unmask_irq, "intr%d:", irq);
73		if (error)
74			return;
75		ithreads[irq] = cur_ith;
76		last_printed +=
77		    snprintf(intrnames + last_printed,
78		    MAXCOMLEN + 1,
79		    "irq%d: %s", irq, name);
80		last_printed++;
81		intrcnt_tab[irq] = intrcnt_index;
82		intrcnt_index++;
83
84	}
85	ithread_add_handler(cur_ith, name, hand, arg,
86	    ithread_priority(flags), flags, cookiep);
87}
88
89int
90arm_remove_irqhandler(void *cookie)
91{
92	return (ithread_remove_handler(cookie));
93}
94
95void dosoftints(void);
96void
97dosoftints(void)
98{
99}
100
101void
102arm_handler_execute(void *frame, int irqnb)
103{
104	struct ithd *ithd;
105	int i;
106	struct intrhand *ih;
107	struct thread *td = curthread;
108
109	td->td_intr_nesting_level++;
110	while ((i = arm_get_next_irq()) != -1) {
111		intrcnt[intrcnt_tab[i]]++;
112		ithd = ithreads[i];
113		if (!ithd)
114			continue;
115		ih = TAILQ_FIRST(&ithd->it_handlers);
116		if (ih && ih->ih_flags & IH_FAST) {
117			TAILQ_FOREACH(ih, &ithd->it_handlers,
118			    ih_next) {
119				ih->ih_handler(ih->ih_argument ?
120				    ih->ih_argument : frame);
121			}
122		} else if (ih) {
123			arm_mask_irq(i);
124			ithread_schedule(ithd);
125		}
126	}
127	td->td_intr_nesting_level--;
128}
129