evsci.c revision 281075
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: evsci - System Control Interrupt configuration and 467754Smsmith * legacy to ACPI mode state transition functions 567754Smsmith * 667754Smsmith ******************************************************************************/ 767754Smsmith 8217365Sjkim/* 9281075Sdim * Copyright (C) 2000 - 2015, Intel Corp. 1070243Smsmith * All rights reserved. 1167754Smsmith * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 2667754Smsmith * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 3067754Smsmith * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 4467754Smsmith 45193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 46193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 47193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 4867754Smsmith 4967754Smsmith 5077424Smsmith#define _COMPONENT ACPI_EVENTS 5191116Smsmith ACPI_MODULE_NAME ("evsci") 5267754Smsmith 53231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 54231844Sjkim 55151937Sjkim/* Local prototypes */ 5667754Smsmith 57151937Sjkimstatic UINT32 ACPI_SYSTEM_XFACE 58151937SjkimAcpiEvSciXruptHandler ( 59151937Sjkim void *Context); 60151937Sjkim 61151937Sjkim 6267754Smsmith/******************************************************************************* 6367754Smsmith * 64254745Sjkim * FUNCTION: AcpiEvSciDispatch 65254745Sjkim * 66254745Sjkim * PARAMETERS: None 67254745Sjkim * 68254745Sjkim * RETURN: Status code indicates whether interrupt was handled. 69254745Sjkim * 70254745Sjkim * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers. 71254745Sjkim * 72254745Sjkim ******************************************************************************/ 73254745Sjkim 74254745SjkimUINT32 75254745SjkimAcpiEvSciDispatch ( 76254745Sjkim void) 77254745Sjkim{ 78254745Sjkim ACPI_SCI_HANDLER_INFO *SciHandler; 79254745Sjkim ACPI_CPU_FLAGS Flags; 80254745Sjkim UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 81254745Sjkim 82254745Sjkim 83254745Sjkim ACPI_FUNCTION_NAME (EvSciDispatch); 84254745Sjkim 85254745Sjkim 86254745Sjkim /* Are there any host-installed SCI handlers? */ 87254745Sjkim 88254745Sjkim if (!AcpiGbl_SciHandlerList) 89254745Sjkim { 90254745Sjkim return (IntStatus); 91254745Sjkim } 92254745Sjkim 93254745Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 94254745Sjkim 95254745Sjkim /* Invoke all host-installed SCI handlers */ 96254745Sjkim 97254745Sjkim SciHandler = AcpiGbl_SciHandlerList; 98254745Sjkim while (SciHandler) 99254745Sjkim { 100254745Sjkim /* Invoke the installed handler (at interrupt level) */ 101254745Sjkim 102254745Sjkim IntStatus |= SciHandler->Address ( 103254745Sjkim SciHandler->Context); 104254745Sjkim 105254745Sjkim SciHandler = SciHandler->Next; 106254745Sjkim } 107254745Sjkim 108254745Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 109254745Sjkim return (IntStatus); 110254745Sjkim} 111254745Sjkim 112254745Sjkim 113254745Sjkim/******************************************************************************* 114254745Sjkim * 115117521Snjl * FUNCTION: AcpiEvSciXruptHandler 11667754Smsmith * 11767754Smsmith * PARAMETERS: Context - Calling Context 11867754Smsmith * 11967754Smsmith * RETURN: Status code indicates whether interrupt was handled. 12067754Smsmith * 12167754Smsmith * DESCRIPTION: Interrupt handler that will figure out what function or 122117521Snjl * control method to call to deal with a SCI. 12367754Smsmith * 12467754Smsmith ******************************************************************************/ 12567754Smsmith 12692388Smsmithstatic UINT32 ACPI_SYSTEM_XFACE 127117521SnjlAcpiEvSciXruptHandler ( 12891116Smsmith void *Context) 12967754Smsmith{ 130117521Snjl ACPI_GPE_XRUPT_INFO *GpeXruptList = Context; 13191116Smsmith UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED; 13267754Smsmith 13367754Smsmith 134167802Sjkim ACPI_FUNCTION_TRACE (EvSciXruptHandler); 13567754Smsmith 13667754Smsmith 13767754Smsmith /* 138281075Sdim * We are guaranteed by the ACPICA initialization/shutdown code that 139114237Snjl * if this interrupt handler is installed, ACPI is enabled. 14067754Smsmith */ 14199679Siwasaki 14267754Smsmith /* 143117521Snjl * Fixed Events: 144117521Snjl * Check for and dispatch any Fixed Events that have occurred 14567754Smsmith */ 14667754Smsmith InterruptHandled |= AcpiEvFixedEventDetect (); 14767754Smsmith 14867754Smsmith /* 149117521Snjl * General Purpose Events: 150117521Snjl * Check for and dispatch any GPEs that have occurred 151117521Snjl */ 152117521Snjl InterruptHandled |= AcpiEvGpeDetect (GpeXruptList); 153117521Snjl 154254745Sjkim /* Invoke all host-installed SCI handlers */ 155254745Sjkim 156254745Sjkim InterruptHandled |= AcpiEvSciDispatch (); 157254745Sjkim 158193267Sjkim AcpiSciCount++; 159246849Sjkim return_UINT32 (InterruptHandled); 160117521Snjl} 161117521Snjl 162117521Snjl 163117521Snjl/******************************************************************************* 164117521Snjl * 165117521Snjl * FUNCTION: AcpiEvGpeXruptHandler 166117521Snjl * 167117521Snjl * PARAMETERS: Context - Calling Context 168117521Snjl * 169117521Snjl * RETURN: Status code indicates whether interrupt was handled. 170117521Snjl * 171117521Snjl * DESCRIPTION: Handler for GPE Block Device interrupts 172117521Snjl * 173117521Snjl ******************************************************************************/ 174117521Snjl 175117521SnjlUINT32 ACPI_SYSTEM_XFACE 176117521SnjlAcpiEvGpeXruptHandler ( 177117521Snjl void *Context) 178117521Snjl{ 179117521Snjl ACPI_GPE_XRUPT_INFO *GpeXruptList = Context; 180117521Snjl UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED; 181117521Snjl 182117521Snjl 183167802Sjkim ACPI_FUNCTION_TRACE (EvGpeXruptHandler); 184117521Snjl 185117521Snjl 186117521Snjl /* 187254745Sjkim * We are guaranteed by the ACPICA initialization/shutdown code that 188117521Snjl * if this interrupt handler is installed, ACPI is enabled. 189117521Snjl */ 190117521Snjl 191193267Sjkim /* GPEs: Check for and dispatch any GPEs that have occurred */ 192193267Sjkim 193117521Snjl InterruptHandled |= AcpiEvGpeDetect (GpeXruptList); 194246849Sjkim return_UINT32 (InterruptHandled); 19567754Smsmith} 19667754Smsmith 19767754Smsmith 19867754Smsmith/****************************************************************************** 19967754Smsmith * 20067754Smsmith * FUNCTION: AcpiEvInstallSciHandler 20167754Smsmith * 20267754Smsmith * PARAMETERS: none 20367754Smsmith * 20467754Smsmith * RETURN: Status 20567754Smsmith * 20667754Smsmith * DESCRIPTION: Installs SCI handler. 20767754Smsmith * 20867754Smsmith ******************************************************************************/ 20967754Smsmith 21067754SmsmithUINT32 211151937SjkimAcpiEvInstallSciHandler ( 212151937Sjkim void) 21367754Smsmith{ 21483174Smsmith UINT32 Status = AE_OK; 21567754Smsmith 21667754Smsmith 217167802Sjkim ACPI_FUNCTION_TRACE (EvInstallSciHandler); 21867754Smsmith 21967754Smsmith 220167802Sjkim Status = AcpiOsInstallInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt, 221167802Sjkim AcpiEvSciXruptHandler, AcpiGbl_GpeXruptListHead); 22283174Smsmith return_ACPI_STATUS (Status); 22367754Smsmith} 22467754Smsmith 22567754Smsmith 22667754Smsmith/****************************************************************************** 22767754Smsmith * 228254745Sjkim * FUNCTION: AcpiEvRemoveAllSciHandlers 22967754Smsmith * 23067754Smsmith * PARAMETERS: none 23167754Smsmith * 232254745Sjkim * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not 23367754Smsmith * installed to begin with 23467754Smsmith * 235193267Sjkim * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be 236254745Sjkim * taken. Remove all host-installed SCI handlers. 23767754Smsmith * 23891116Smsmith * Note: It doesn't seem important to disable all events or set the event 239193267Sjkim * enable registers to their original values. The OS should disable 24091116Smsmith * the SCI interrupt level when the handler is removed, so no more 24191116Smsmith * events will come in. 24291116Smsmith * 24367754Smsmith ******************************************************************************/ 24467754Smsmith 24567754SmsmithACPI_STATUS 246254745SjkimAcpiEvRemoveAllSciHandlers ( 247151937Sjkim void) 24867754Smsmith{ 249254745Sjkim ACPI_SCI_HANDLER_INFO *SciHandler; 250254745Sjkim ACPI_CPU_FLAGS Flags; 25199679Siwasaki ACPI_STATUS Status; 25299679Siwasaki 25399679Siwasaki 254254745Sjkim ACPI_FUNCTION_TRACE (EvRemoveAllSciHandlers); 25567754Smsmith 25683174Smsmith 25791116Smsmith /* Just let the OS remove the handler and disable the level */ 25867754Smsmith 259167802Sjkim Status = AcpiOsRemoveInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt, 260167802Sjkim AcpiEvSciXruptHandler); 26167754Smsmith 262254745Sjkim if (!AcpiGbl_SciHandlerList) 263254745Sjkim { 264254745Sjkim return (Status); 265254745Sjkim } 266254745Sjkim 267254745Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 268254745Sjkim 269254745Sjkim /* Free all host-installed SCI handlers */ 270254745Sjkim 271254745Sjkim while (AcpiGbl_SciHandlerList) 272254745Sjkim { 273254745Sjkim SciHandler = AcpiGbl_SciHandlerList; 274254745Sjkim AcpiGbl_SciHandlerList = SciHandler->Next; 275254745Sjkim ACPI_FREE (SciHandler); 276254745Sjkim } 277254745Sjkim 278254745Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 27999679Siwasaki return_ACPI_STATUS (Status); 28067754Smsmith} 28167754Smsmith 282231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */ 283