1 /* $NetBSD: OsdInterrupt.c,v 1.7 2007/12/15 00:39:25 perry Exp $ */
4 * Copyright 2001 Wasabi Systems, Inc.
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
41 * 6.5: Interrupt Handling
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: OsdInterrupt.c,v 1.7 2007/12/15 00:39:25 perry Exp $");
47 #include <sys/param.h>
48 #include <sys/malloc.h>
49 #include <sys/mutex.h>
50 #include <sys/queue.h>
52 #include <dev/acpi/acpica.h>
54 #include <machine/acpi_machdep.h>
56 #define _COMPONENT ACPI_OS_SERVICES
57 ACPI_MODULE_NAME("INTERRUPT")
59 MALLOC_DEFINE(M_ACPI
, "acpi", "Advanced Configuration and Power Interface");
62 * We're lucky -- ACPI uses the same convention for interrupt service
63 * routine return values at NetBSD does -- so we can just ask MD code
64 * to hook it up directly (ACPI interrupts are always level triggered
65 * and shareable, and return 0 for "not handled" and 1 for "handled").
68 struct acpi_interrupt_handler
{
69 LIST_ENTRY(acpi_interrupt_handler
) aih_list
;
71 ACPI_OSD_HANDLER aih_func
;
75 static LIST_HEAD(, acpi_interrupt_handler
) acpi_interrupt_list
=
76 LIST_HEAD_INITIALIZER(&acpi_interrupt_list
);
78 kmutex_t acpi_interrupt_list_mtx
;
81 * AcpiOsInstallInterruptHandler:
83 * Install a handler for a hardware interrupt level.
86 AcpiOsInstallInterruptHandler(UINT32 InterruptNumber
,
87 ACPI_OSD_HANDLER ServiceRoutine
, void *Context
)
89 struct acpi_interrupt_handler
*aih
;
92 if (InterruptNumber
> 255)
93 return AE_BAD_PARAMETER
;
94 if (ServiceRoutine
== NULL
)
95 return AE_BAD_PARAMETER
;
97 aih
= malloc(sizeof(*aih
), M_ACPI
, M_NOWAIT
);
101 aih
->aih_intrnum
= InterruptNumber
;
102 aih
->aih_func
= ServiceRoutine
;
104 rv
= acpi_md_OsInstallInterruptHandler(InterruptNumber
,
105 ServiceRoutine
, Context
, &aih
->aih_ih
);
107 mutex_enter(&acpi_interrupt_list_mtx
);
108 LIST_INSERT_HEAD(&acpi_interrupt_list
, aih
, aih_list
);
109 mutex_exit(&acpi_interrupt_list_mtx
);
117 * AcpiOsRemoveInterruptHandler:
119 * Remove an interrupt handler.
122 AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber
,
123 ACPI_OSD_HANDLER ServiceRoutine
)
125 struct acpi_interrupt_handler
*aih
;
127 if (InterruptNumber
> 255)
128 return AE_BAD_PARAMETER
;
129 if (ServiceRoutine
== NULL
)
130 return AE_BAD_PARAMETER
;
132 mutex_enter(&acpi_interrupt_list_mtx
);
133 LIST_FOREACH(aih
, &acpi_interrupt_list
, aih_list
) {
134 if (aih
->aih_intrnum
== InterruptNumber
&&
135 aih
->aih_func
== ServiceRoutine
) {
136 LIST_REMOVE(aih
, aih_list
);
137 mutex_exit(&acpi_interrupt_list_mtx
);
138 acpi_md_OsRemoveInterruptHandler(aih
->aih_ih
);
143 mutex_exit(&acpi_interrupt_list_mtx
);