195b482a8SLen Brown /******************************************************************************* 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: evsci - System Control Interrupt configuration and 495b482a8SLen Brown * legacy to ACPI mode state transition functions 595b482a8SLen Brown * 695b482a8SLen Brown ******************************************************************************/ 795b482a8SLen Brown 895b482a8SLen Brown /* 925f044e6SBob Moore * Copyright (C) 2000 - 2013, Intel Corp. 1095b482a8SLen Brown * All rights reserved. 1195b482a8SLen Brown * 1295b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 1395b482a8SLen Brown * modification, are permitted provided that the following conditions 1495b482a8SLen Brown * are met: 1595b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 1695b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 1795b482a8SLen Brown * without modification. 1895b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1995b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 2095b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 2195b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 2295b482a8SLen Brown * binary redistribution. 2395b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 2495b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 2595b482a8SLen Brown * from this software without specific prior written permission. 2695b482a8SLen Brown * 2795b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 2895b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 2995b482a8SLen Brown * Software Foundation. 3095b482a8SLen Brown * 3195b482a8SLen Brown * NO WARRANTY 3295b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3395b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3495b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3595b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3695b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3795b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3895b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3995b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4095b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4195b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4295b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 4395b482a8SLen Brown */ 4495b482a8SLen Brown 4595b482a8SLen Brown #include <acpi/acpi.h> 46e2f7a777SLen Brown #include "accommon.h" 47e2f7a777SLen Brown #include "acevents.h" 4895b482a8SLen Brown 4995b482a8SLen Brown #define _COMPONENT ACPI_EVENTS 5095b482a8SLen Brown ACPI_MODULE_NAME("evsci") 5133620c54SBob Moore #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 5295b482a8SLen Brown /* Local prototypes */ 5395b482a8SLen Brown static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context); 5495b482a8SLen Brown 5595b482a8SLen Brown /******************************************************************************* 5695b482a8SLen Brown * 57a2fd4b4bSLv Zheng * FUNCTION: acpi_ev_sci_dispatch 58a2fd4b4bSLv Zheng * 59a2fd4b4bSLv Zheng * PARAMETERS: None 60a2fd4b4bSLv Zheng * 61a2fd4b4bSLv Zheng * RETURN: Status code indicates whether interrupt was handled. 62a2fd4b4bSLv Zheng * 63a2fd4b4bSLv Zheng * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers. 64a2fd4b4bSLv Zheng * 65a2fd4b4bSLv Zheng ******************************************************************************/ 66a2fd4b4bSLv Zheng 67a2fd4b4bSLv Zheng u32 acpi_ev_sci_dispatch(void) 68a2fd4b4bSLv Zheng { 69a2fd4b4bSLv Zheng struct acpi_sci_handler_info *sci_handler; 70a2fd4b4bSLv Zheng acpi_cpu_flags flags; 71a2fd4b4bSLv Zheng u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; 72a2fd4b4bSLv Zheng 73a2fd4b4bSLv Zheng ACPI_FUNCTION_NAME(ev_sci_dispatch); 74a2fd4b4bSLv Zheng 75a2fd4b4bSLv Zheng /* Are there any host-installed SCI handlers? */ 76a2fd4b4bSLv Zheng 77a2fd4b4bSLv Zheng if (!acpi_gbl_sci_handler_list) { 78a2fd4b4bSLv Zheng return (int_status); 79a2fd4b4bSLv Zheng } 80a2fd4b4bSLv Zheng 81a2fd4b4bSLv Zheng flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 82a2fd4b4bSLv Zheng 83a2fd4b4bSLv Zheng /* Invoke all host-installed SCI handlers */ 84a2fd4b4bSLv Zheng 85a2fd4b4bSLv Zheng sci_handler = acpi_gbl_sci_handler_list; 86a2fd4b4bSLv Zheng while (sci_handler) { 87a2fd4b4bSLv Zheng 88a2fd4b4bSLv Zheng /* Invoke the installed handler (at interrupt level) */ 89a2fd4b4bSLv Zheng 90c53ae3a6SBob Moore int_status |= sci_handler->address(sci_handler->context); 91a2fd4b4bSLv Zheng 92a2fd4b4bSLv Zheng sci_handler = sci_handler->next; 93a2fd4b4bSLv Zheng } 94a2fd4b4bSLv Zheng 95a2fd4b4bSLv Zheng acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 96a2fd4b4bSLv Zheng return (int_status); 97a2fd4b4bSLv Zheng } 98a2fd4b4bSLv Zheng 99a2fd4b4bSLv Zheng /******************************************************************************* 100a2fd4b4bSLv Zheng * 10195b482a8SLen Brown * FUNCTION: acpi_ev_sci_xrupt_handler 10295b482a8SLen Brown * 103ba494beeSBob Moore * PARAMETERS: context - Calling Context 10495b482a8SLen Brown * 10595b482a8SLen Brown * RETURN: Status code indicates whether interrupt was handled. 10695b482a8SLen Brown * 10795b482a8SLen Brown * DESCRIPTION: Interrupt handler that will figure out what function or 10895b482a8SLen Brown * control method to call to deal with a SCI. 10995b482a8SLen Brown * 11095b482a8SLen Brown ******************************************************************************/ 11195b482a8SLen Brown 11295b482a8SLen Brown static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) 11395b482a8SLen Brown { 11495b482a8SLen Brown struct acpi_gpe_xrupt_info *gpe_xrupt_list = context; 11595b482a8SLen Brown u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; 11695b482a8SLen Brown 11795b482a8SLen Brown ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); 11895b482a8SLen Brown 11995b482a8SLen Brown /* 12095b482a8SLen Brown * We are guaranteed by the ACPI CA initialization/shutdown code that 12195b482a8SLen Brown * if this interrupt handler is installed, ACPI is enabled. 12295b482a8SLen Brown */ 12395b482a8SLen Brown 12495b482a8SLen Brown /* 12595b482a8SLen Brown * Fixed Events: 12695b482a8SLen Brown * Check for and dispatch any Fixed Events that have occurred 12795b482a8SLen Brown */ 12895b482a8SLen Brown interrupt_handled |= acpi_ev_fixed_event_detect(); 12995b482a8SLen Brown 13095b482a8SLen Brown /* 13195b482a8SLen Brown * General Purpose Events: 13295b482a8SLen Brown * Check for and dispatch any GPEs that have occurred 13395b482a8SLen Brown */ 13495b482a8SLen Brown interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); 13595b482a8SLen Brown 136a2fd4b4bSLv Zheng /* Invoke all host-installed SCI handlers */ 137a2fd4b4bSLv Zheng 138a2fd4b4bSLv Zheng interrupt_handled |= acpi_ev_sci_dispatch(); 139a2fd4b4bSLv Zheng 140*9187a415SLv Zheng acpi_sci_count++; 141fd1af712SBob Moore return_UINT32(interrupt_handled); 14295b482a8SLen Brown } 14395b482a8SLen Brown 14495b482a8SLen Brown /******************************************************************************* 14595b482a8SLen Brown * 14695b482a8SLen Brown * FUNCTION: acpi_ev_gpe_xrupt_handler 14795b482a8SLen Brown * 148ba494beeSBob Moore * PARAMETERS: context - Calling Context 14995b482a8SLen Brown * 15095b482a8SLen Brown * RETURN: Status code indicates whether interrupt was handled. 15195b482a8SLen Brown * 15295b482a8SLen Brown * DESCRIPTION: Handler for GPE Block Device interrupts 15395b482a8SLen Brown * 15495b482a8SLen Brown ******************************************************************************/ 15595b482a8SLen Brown 15695b482a8SLen Brown u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context) 15795b482a8SLen Brown { 15895b482a8SLen Brown struct acpi_gpe_xrupt_info *gpe_xrupt_list = context; 15995b482a8SLen Brown u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; 16095b482a8SLen Brown 16195b482a8SLen Brown ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler); 16295b482a8SLen Brown 16395b482a8SLen Brown /* 16495b482a8SLen Brown * We are guaranteed by the ACPICA initialization/shutdown code that 16595b482a8SLen Brown * if this interrupt handler is installed, ACPI is enabled. 16695b482a8SLen Brown */ 16795b482a8SLen Brown 16895b482a8SLen Brown /* GPEs: Check for and dispatch any GPEs that have occurred */ 16995b482a8SLen Brown 17095b482a8SLen Brown interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); 171fd1af712SBob Moore return_UINT32(interrupt_handled); 17295b482a8SLen Brown } 17395b482a8SLen Brown 17495b482a8SLen Brown /****************************************************************************** 17595b482a8SLen Brown * 17695b482a8SLen Brown * FUNCTION: acpi_ev_install_sci_handler 17795b482a8SLen Brown * 17895b482a8SLen Brown * PARAMETERS: none 17995b482a8SLen Brown * 18095b482a8SLen Brown * RETURN: Status 18195b482a8SLen Brown * 18295b482a8SLen Brown * DESCRIPTION: Installs SCI handler. 18395b482a8SLen Brown * 18495b482a8SLen Brown ******************************************************************************/ 18595b482a8SLen Brown 18695b482a8SLen Brown u32 acpi_ev_install_sci_handler(void) 18795b482a8SLen Brown { 18895b482a8SLen Brown u32 status = AE_OK; 18995b482a8SLen Brown 19095b482a8SLen Brown ACPI_FUNCTION_TRACE(ev_install_sci_handler); 19195b482a8SLen Brown 19295b482a8SLen Brown status = 19395b482a8SLen Brown acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, 19495b482a8SLen Brown acpi_ev_sci_xrupt_handler, 19595b482a8SLen Brown acpi_gbl_gpe_xrupt_list_head); 19695b482a8SLen Brown return_ACPI_STATUS(status); 19795b482a8SLen Brown } 19895b482a8SLen Brown 19995b482a8SLen Brown /****************************************************************************** 20095b482a8SLen Brown * 201a2fd4b4bSLv Zheng * FUNCTION: acpi_ev_remove_all_sci_handlers 20295b482a8SLen Brown * 20395b482a8SLen Brown * PARAMETERS: none 20495b482a8SLen Brown * 205a2fd4b4bSLv Zheng * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not 20695b482a8SLen Brown * installed to begin with 20795b482a8SLen Brown * 20895b482a8SLen Brown * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be 209a2fd4b4bSLv Zheng * taken. Remove all host-installed SCI handlers. 21095b482a8SLen Brown * 21195b482a8SLen Brown * Note: It doesn't seem important to disable all events or set the event 21295b482a8SLen Brown * enable registers to their original values. The OS should disable 21395b482a8SLen Brown * the SCI interrupt level when the handler is removed, so no more 21495b482a8SLen Brown * events will come in. 21595b482a8SLen Brown * 21695b482a8SLen Brown ******************************************************************************/ 21795b482a8SLen Brown 218a2fd4b4bSLv Zheng acpi_status acpi_ev_remove_all_sci_handlers(void) 21995b482a8SLen Brown { 220a2fd4b4bSLv Zheng struct acpi_sci_handler_info *sci_handler; 221a2fd4b4bSLv Zheng acpi_cpu_flags flags; 22295b482a8SLen Brown acpi_status status; 22395b482a8SLen Brown 224a2fd4b4bSLv Zheng ACPI_FUNCTION_TRACE(ev_remove_all_sci_handlers); 22595b482a8SLen Brown 22695b482a8SLen Brown /* Just let the OS remove the handler and disable the level */ 22795b482a8SLen Brown 22895b482a8SLen Brown status = 22995b482a8SLen Brown acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, 23095b482a8SLen Brown acpi_ev_sci_xrupt_handler); 23195b482a8SLen Brown 232a2fd4b4bSLv Zheng if (!acpi_gbl_sci_handler_list) { 233a2fd4b4bSLv Zheng return (status); 234a2fd4b4bSLv Zheng } 235a2fd4b4bSLv Zheng 236a2fd4b4bSLv Zheng flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 237a2fd4b4bSLv Zheng 238a2fd4b4bSLv Zheng /* Free all host-installed SCI handlers */ 239a2fd4b4bSLv Zheng 240a2fd4b4bSLv Zheng while (acpi_gbl_sci_handler_list) { 241a2fd4b4bSLv Zheng sci_handler = acpi_gbl_sci_handler_list; 242a2fd4b4bSLv Zheng acpi_gbl_sci_handler_list = sci_handler->next; 243a2fd4b4bSLv Zheng ACPI_FREE(sci_handler); 244a2fd4b4bSLv Zheng } 245a2fd4b4bSLv Zheng 246a2fd4b4bSLv Zheng acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 24795b482a8SLen Brown return_ACPI_STATUS(status); 24895b482a8SLen Brown } 24933620c54SBob Moore 25033620c54SBob Moore #endif /* !ACPI_REDUCED_HARDWARE */ 251