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