Home | History | Annotate | Line # | Download | only in acpica
OsdInterrupt.c revision 1.6.30.1
      1  1.6.30.1    bouyer /*	$NetBSD: OsdInterrupt.c,v 1.6.30.1 2008/01/02 21:53:53 bouyer Exp $	*/
      2       1.1     kochi 
      3       1.1     kochi /*
      4       1.1     kochi  * Copyright 2001 Wasabi Systems, Inc.
      5       1.1     kochi  * All rights reserved.
      6       1.1     kochi  *
      7       1.1     kochi  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
      8       1.1     kochi  *
      9       1.1     kochi  * Redistribution and use in source and binary forms, with or without
     10       1.1     kochi  * modification, are permitted provided that the following conditions
     11       1.1     kochi  * are met:
     12       1.1     kochi  * 1. Redistributions of source code must retain the above copyright
     13       1.1     kochi  *    notice, this list of conditions and the following disclaimer.
     14       1.1     kochi  * 2. Redistributions in binary form must reproduce the above copyright
     15       1.1     kochi  *    notice, this list of conditions and the following disclaimer in the
     16       1.1     kochi  *    documentation and/or other materials provided with the distribution.
     17       1.1     kochi  * 3. All advertising materials mentioning features or use of this software
     18       1.1     kochi  *    must display the following acknowledgement:
     19       1.1     kochi  *	This product includes software developed for the NetBSD Project by
     20       1.1     kochi  *	Wasabi Systems, Inc.
     21       1.1     kochi  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22       1.1     kochi  *    or promote products derived from this software without specific prior
     23       1.1     kochi  *    written permission.
     24       1.1     kochi  *
     25       1.1     kochi  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26       1.1     kochi  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27       1.1     kochi  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28       1.1     kochi  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29       1.1     kochi  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30       1.1     kochi  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31       1.1     kochi  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32       1.1     kochi  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33       1.1     kochi  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34       1.1     kochi  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35       1.1     kochi  * POSSIBILITY OF SUCH DAMAGE.
     36       1.1     kochi  */
     37       1.1     kochi 
     38       1.1     kochi /*
     39       1.1     kochi  * OS Services Layer
     40       1.1     kochi  *
     41       1.1     kochi  * 6.5: Interrupt Handling
     42       1.1     kochi  */
     43       1.1     kochi 
     44       1.1     kochi #include <sys/cdefs.h>
     45  1.6.30.1    bouyer __KERNEL_RCSID(0, "$NetBSD: OsdInterrupt.c,v 1.6.30.1 2008/01/02 21:53:53 bouyer Exp $");
     46       1.1     kochi 
     47       1.1     kochi #include <sys/param.h>
     48       1.1     kochi #include <sys/malloc.h>
     49       1.3   xtraeme #include <sys/mutex.h>
     50       1.1     kochi #include <sys/queue.h>
     51       1.1     kochi 
     52       1.1     kochi #include <dev/acpi/acpica.h>
     53       1.1     kochi 
     54       1.1     kochi #include <machine/acpi_machdep.h>
     55       1.1     kochi 
     56       1.1     kochi #define	_COMPONENT	ACPI_OS_SERVICES
     57       1.1     kochi ACPI_MODULE_NAME("INTERRUPT")
     58       1.1     kochi 
     59       1.1     kochi MALLOC_DEFINE(M_ACPI, "acpi", "Advanced Configuration and Power Interface");
     60       1.1     kochi 
     61       1.1     kochi /*
     62       1.1     kochi  * We're lucky -- ACPI uses the same convention for interrupt service
     63       1.1     kochi  * routine return values at NetBSD does -- so we can just ask MD code
     64       1.1     kochi  * to hook it up directly (ACPI interrupts are always level triggered
     65       1.1     kochi  * and shareable, and return 0 for "not handled" and 1 for "handled").
     66       1.1     kochi  */
     67       1.1     kochi 
     68       1.1     kochi struct acpi_interrupt_handler {
     69       1.1     kochi 	LIST_ENTRY(acpi_interrupt_handler) aih_list;
     70       1.1     kochi 	UINT32 aih_intrnum;
     71       1.1     kochi 	ACPI_OSD_HANDLER aih_func;
     72       1.1     kochi 	void *aih_ih;
     73       1.1     kochi };
     74       1.1     kochi 
     75       1.1     kochi static LIST_HEAD(, acpi_interrupt_handler) acpi_interrupt_list =
     76       1.1     kochi     LIST_HEAD_INITIALIZER(&acpi_interrupt_list);
     77       1.6        ad 
     78       1.6        ad kmutex_t acpi_interrupt_list_mtx;
     79       1.1     kochi 
     80       1.1     kochi /*
     81       1.1     kochi  * AcpiOsInstallInterruptHandler:
     82       1.1     kochi  *
     83       1.1     kochi  *	Install a handler for a hardware interrupt level.
     84       1.1     kochi  */
     85       1.1     kochi ACPI_STATUS
     86       1.1     kochi AcpiOsInstallInterruptHandler(UINT32 InterruptNumber,
     87       1.1     kochi     ACPI_OSD_HANDLER ServiceRoutine, void *Context)
     88       1.1     kochi {
     89       1.1     kochi 	struct acpi_interrupt_handler *aih;
     90       1.1     kochi 	ACPI_STATUS rv;
     91       1.1     kochi 
     92  1.6.30.1    bouyer 	ACPI_FUNCTION_TRACE(__func__);
     93       1.1     kochi 
     94       1.2  christos 	if (InterruptNumber > 255)
     95       1.1     kochi 		return_ACPI_STATUS(AE_BAD_PARAMETER);
     96       1.1     kochi 	if (ServiceRoutine == NULL)
     97       1.1     kochi 		return_ACPI_STATUS(AE_BAD_PARAMETER);
     98       1.1     kochi 
     99       1.1     kochi 	aih = malloc(sizeof(*aih), M_ACPI, M_NOWAIT);
    100       1.1     kochi 	if (aih == NULL)
    101       1.1     kochi 		return_ACPI_STATUS(AE_NO_MEMORY);
    102       1.1     kochi 
    103       1.1     kochi 	aih->aih_intrnum = InterruptNumber;
    104       1.1     kochi 	aih->aih_func = ServiceRoutine;
    105       1.1     kochi 
    106       1.1     kochi 	rv = acpi_md_OsInstallInterruptHandler(InterruptNumber,
    107       1.1     kochi 	    ServiceRoutine, Context, &aih->aih_ih);
    108       1.1     kochi 	if (rv == AE_OK) {
    109       1.4   xtraeme 		mutex_enter(&acpi_interrupt_list_mtx);
    110       1.1     kochi 		LIST_INSERT_HEAD(&acpi_interrupt_list, aih, aih_list);
    111       1.4   xtraeme 		mutex_exit(&acpi_interrupt_list_mtx);
    112       1.1     kochi 	} else
    113       1.1     kochi 		free(aih, M_ACPI);
    114       1.1     kochi 
    115       1.1     kochi 	return_ACPI_STATUS(rv);
    116       1.1     kochi }
    117       1.1     kochi 
    118       1.1     kochi /*
    119       1.1     kochi  * AcpiOsRemoveInterruptHandler:
    120       1.1     kochi  *
    121       1.1     kochi  *	Remove an interrupt handler.
    122       1.1     kochi  */
    123       1.1     kochi ACPI_STATUS
    124       1.1     kochi AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber,
    125       1.1     kochi     ACPI_OSD_HANDLER ServiceRoutine)
    126       1.1     kochi {
    127       1.1     kochi 	struct acpi_interrupt_handler *aih;
    128       1.1     kochi 
    129  1.6.30.1    bouyer 	ACPI_FUNCTION_TRACE(__func__);
    130       1.1     kochi 
    131       1.2  christos 	if (InterruptNumber > 255)
    132       1.1     kochi 		return_ACPI_STATUS(AE_BAD_PARAMETER);
    133       1.1     kochi 	if (ServiceRoutine == NULL)
    134       1.1     kochi 		return_ACPI_STATUS(AE_BAD_PARAMETER);
    135       1.1     kochi 
    136       1.4   xtraeme 	mutex_enter(&acpi_interrupt_list_mtx);
    137       1.1     kochi 	LIST_FOREACH(aih, &acpi_interrupt_list, aih_list) {
    138       1.1     kochi 		if (aih->aih_intrnum == InterruptNumber &&
    139       1.1     kochi 		    aih->aih_func == ServiceRoutine) {
    140       1.1     kochi 			LIST_REMOVE(aih, aih_list);
    141       1.4   xtraeme 			mutex_exit(&acpi_interrupt_list_mtx);
    142       1.1     kochi 			acpi_md_OsRemoveInterruptHandler(aih->aih_ih);
    143       1.1     kochi 			free(aih, M_ACPI);
    144       1.1     kochi 			return_ACPI_STATUS(AE_OK);
    145       1.1     kochi 		}
    146       1.1     kochi 	}
    147       1.4   xtraeme 	mutex_exit(&acpi_interrupt_list_mtx);
    148       1.1     kochi 	return_ACPI_STATUS(AE_NOT_EXIST);
    149       1.1     kochi }
    150