Index: sys/arch/x86/include/acpi_machdep.h =================================================================== RCS file: /home/joerg/repo/netbsd/src/sys/arch/x86/include/acpi_machdep.h,v retrieving revision 1.5 diff -u -p -r1.5 acpi_machdep.h --- sys/arch/x86/include/acpi_machdep.h 14 Mar 2009 13:54:28 -0000 1.5 +++ sys/arch/x86/include/acpi_machdep.h 16 Jul 2010 20:09:42 -0000 @@ -73,3 +73,4 @@ void acpi_md_OsEnableInterrupt(void); int acpi_md_sleep(int); void acpi_md_sleep_init(void); void acpi_md_callback(void); +void acpi_mi_callback(void); Index: sys/dev/acpi/acpi.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/sys/dev/acpi/acpi.c,v retrieving revision 1.206 diff -u -p -r1.206 acpi.c --- sys/dev/acpi/acpi.c 10 Jul 2010 13:08:09 -0000 1.206 +++ sys/dev/acpi/acpi.c 16 Jul 2010 20:10:19 -0000 @@ -474,20 +474,7 @@ acpi_attach(device_t parent, device_t se acpi_osd_debugger(); #endif -#define ACPI_ENABLE_PHASE1 \ - (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT) -#define ACPI_ENABLE_PHASE2 \ - (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \ - ACPI_NO_ADDRESS_SPACE_INIT) - - rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1); - - if (ACPI_FAILURE(rv)) - goto fail; - - acpi_md_callback(); - - rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2); + rv = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE(rv)) goto fail; @@ -517,6 +504,9 @@ acpi_attach(device_t parent, device_t se if (ACPI_FAILURE(rv)) goto fail; + acpi_md_callback(); + acpi_mi_callback(); + acpi_active = 1; /* Show SCI interrupt. */ Index: sys/dev/acpi/acpica/OsdInterrupt.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/sys/dev/acpi/acpica/OsdInterrupt.c,v retrieving revision 1.8 diff -u -p -r1.8 OsdInterrupt.c --- sys/dev/acpi/acpica/OsdInterrupt.c 18 Aug 2009 16:41:02 -0000 1.8 +++ sys/dev/acpi/acpica/OsdInterrupt.c 16 Jul 2010 20:09:42 -0000 @@ -69,9 +69,12 @@ struct acpi_interrupt_handler { LIST_ENTRY(acpi_interrupt_handler) aih_list; UINT32 aih_intrnum; ACPI_OSD_HANDLER aih_func; + void *aih_context; void *aih_ih; + int aih_deferred; }; +static int pre_acpi_md_callback = 1; static LIST_HEAD(, acpi_interrupt_handler) acpi_interrupt_list = LIST_HEAD_INITIALIZER(&acpi_interrupt_list); @@ -100,6 +103,15 @@ AcpiOsInstallInterruptHandler(UINT32 Int aih->aih_intrnum = InterruptNumber; aih->aih_func = ServiceRoutine; + aih->aih_context = Context; + aih->aih_deferred = pre_acpi_md_callback; + + if (pre_acpi_md_callback) { + mutex_enter(&acpi_interrupt_list_mtx); + LIST_INSERT_HEAD(&acpi_interrupt_list, aih, aih_list); + mutex_exit(&acpi_interrupt_list_mtx); + return AE_OK; + } rv = acpi_md_OsInstallInterruptHandler(InterruptNumber, ServiceRoutine, Context, &aih->aih_ih); @@ -113,6 +125,27 @@ AcpiOsInstallInterruptHandler(UINT32 Int return rv; } +void +acpi_mi_callback(void) +{ + struct acpi_interrupt_handler *aih; + ACPI_STATUS rv; + + mutex_enter(&acpi_interrupt_list_mtx); + + LIST_FOREACH(aih, &acpi_interrupt_list, aih_list) { + rv = acpi_md_OsInstallInterruptHandler(aih->aih_intrnum, + aih->aih_func, aih->aih_context, &aih->aih_ih); + if (rv != AE_OK) + panic("Unable to setup deferred ACPI interrupt"); + aih->aih_deferred = 0; + } + + pre_acpi_md_callback = 0; + + mutex_exit(&acpi_interrupt_list_mtx); +} + /* * AcpiOsRemoveInterruptHandler: * @@ -135,7 +168,8 @@ AcpiOsRemoveInterruptHandler(UINT32 Inte aih->aih_func == ServiceRoutine) { LIST_REMOVE(aih, aih_list); mutex_exit(&acpi_interrupt_list_mtx); - acpi_md_OsRemoveInterruptHandler(aih->aih_ih); + if (aih->aih_deferred == 0) + acpi_md_OsRemoveInterruptHandler(aih->aih_ih); free(aih, M_ACPI); return AE_OK; }