intr.c revision 153666
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 153666 2005-12-22 22:16:09Z jhb $");
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 intr_event *intr_events[NIRQ];
54static int intrcnt_tab[NIRQ];
55static int intrcnt_index = 0;
56static int last_printed = 0;
57
58void	arm_handler_execute(struct trapframe *, int);
59
60void
61arm_setup_irqhandler(const char *name, void (*hand)(void*), void *arg,
62    int irq, int flags, void **cookiep)
63{
64	struct intr_event *event;
65	int error;
66
67	if (irq < 0 || irq >= NIRQ)
68		return;
69	event = intr_events[irq];
70	if (event == NULL) {
71		error = intr_event_create(&event, (void *)irq, 0,
72		    (void (*)(void *))arm_unmask_irq, "intr%d:", irq);
73		if (error)
74			return;
75		intr_events[irq] = event;
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	intr_event_add_handler(event, name, hand, arg,
86	    intr_priority(flags), flags, cookiep);
87}
88
89int
90arm_remove_irqhandler(void *cookie)
91{
92	return (intr_event_remove_handler(cookie));
93}
94
95void dosoftints(void);
96void
97dosoftints(void)
98{
99}
100
101void
102arm_handler_execute(struct trapframe *frame, int irqnb)
103{
104	struct intr_event *event;
105	struct intr_handler *ih;
106	struct thread *td = curthread;
107	int i, thread;
108
109	td->td_intr_nesting_level++;
110	while ((i = arm_get_next_irq()) != -1) {
111		arm_mask_irq(i);
112		intrcnt[intrcnt_tab[i]]++;
113		event = intr_events[i];
114		if (!event || TAILQ_EMPTY(&event->ie_handlers))
115			continue;
116
117		/* Execute fast handlers. */
118		thread = 0;
119		TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
120			if (!(ih->ih_flags & IH_FAST))
121				thread = 1;
122			else
123				ih->ih_handler(ih->ih_argument ?
124				    ih->ih_argument : frame);
125		}
126
127		/* Schedule thread if needed. */
128		if (thread)
129			intr_event_schedule_thread(event);
130		else
131			arm_unmask_irq(i);
132	}
133	td->td_intr_nesting_level--;
134}
135