215 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/*******************************************************************************3 *4 * Module Name: evsci - System Control Interrupt configuration and5 * legacy to ACPI mode state transition functions6 *7 ******************************************************************************/8 9#include <acpi/acpi.h>10#include "accommon.h"11#include "acevents.h"12 13#define _COMPONENT ACPI_EVENTS14ACPI_MODULE_NAME("evsci")15#if (!ACPI_REDUCED_HARDWARE) /* Entire module */16/* Local prototypes */17static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context);18 19/*******************************************************************************20 *21 * FUNCTION: acpi_ev_sci_dispatch22 *23 * PARAMETERS: None24 *25 * RETURN: Status code indicates whether interrupt was handled.26 *27 * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers.28 *29 ******************************************************************************/30 31u32 acpi_ev_sci_dispatch(void)32{33 struct acpi_sci_handler_info *sci_handler;34 acpi_cpu_flags flags;35 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;36 37 ACPI_FUNCTION_NAME(ev_sci_dispatch);38 39 /* Are there any host-installed SCI handlers? */40 41 if (!acpi_gbl_sci_handler_list) {42 return (int_status);43 }44 45 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);46 47 /* Invoke all host-installed SCI handlers */48 49 sci_handler = acpi_gbl_sci_handler_list;50 while (sci_handler) {51 52 /* Invoke the installed handler (at interrupt level) */53 54 int_status |= sci_handler->address(sci_handler->context);55 56 sci_handler = sci_handler->next;57 }58 59 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);60 return (int_status);61}62 63/*******************************************************************************64 *65 * FUNCTION: acpi_ev_sci_xrupt_handler66 *67 * PARAMETERS: context - Calling Context68 *69 * RETURN: Status code indicates whether interrupt was handled.70 *71 * DESCRIPTION: Interrupt handler that will figure out what function or72 * control method to call to deal with a SCI.73 *74 ******************************************************************************/75 76static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)77{78 struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;79 u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;80 81 ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler);82 83 /*84 * We are guaranteed by the ACPICA initialization/shutdown code that85 * if this interrupt handler is installed, ACPI is enabled.86 */87 88 /*89 * Fixed Events:90 * Check for and dispatch any Fixed Events that have occurred91 */92 interrupt_handled |= acpi_ev_fixed_event_detect();93 94 /*95 * General Purpose Events:96 * Check for and dispatch any GPEs that have occurred97 */98 interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);99 100 /* Invoke all host-installed SCI handlers */101 102 interrupt_handled |= acpi_ev_sci_dispatch();103 104 acpi_sci_count++;105 return_UINT32(interrupt_handled);106}107 108/*******************************************************************************109 *110 * FUNCTION: acpi_ev_gpe_xrupt_handler111 *112 * PARAMETERS: context - Calling Context113 *114 * RETURN: Status code indicates whether interrupt was handled.115 *116 * DESCRIPTION: Handler for GPE Block Device interrupts117 *118 ******************************************************************************/119 120u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context)121{122 struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;123 u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;124 125 ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler);126 127 /*128 * We are guaranteed by the ACPICA initialization/shutdown code that129 * if this interrupt handler is installed, ACPI is enabled.130 */131 132 /* GPEs: Check for and dispatch any GPEs that have occurred */133 134 interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);135 return_UINT32(interrupt_handled);136}137 138/******************************************************************************139 *140 * FUNCTION: acpi_ev_install_sci_handler141 *142 * PARAMETERS: none143 *144 * RETURN: Status145 *146 * DESCRIPTION: Installs SCI handler.147 *148 ******************************************************************************/149 150u32 acpi_ev_install_sci_handler(void)151{152 u32 status = AE_OK;153 154 ACPI_FUNCTION_TRACE(ev_install_sci_handler);155 156 status =157 acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,158 acpi_ev_sci_xrupt_handler,159 acpi_gbl_gpe_xrupt_list_head);160 return_ACPI_STATUS(status);161}162 163/******************************************************************************164 *165 * FUNCTION: acpi_ev_remove_all_sci_handlers166 *167 * PARAMETERS: none168 *169 * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not170 * installed to begin with171 *172 * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be173 * taken. Remove all host-installed SCI handlers.174 *175 * Note: It doesn't seem important to disable all events or set the event176 * enable registers to their original values. The OS should disable177 * the SCI interrupt level when the handler is removed, so no more178 * events will come in.179 *180 ******************************************************************************/181 182acpi_status acpi_ev_remove_all_sci_handlers(void)183{184 struct acpi_sci_handler_info *sci_handler;185 acpi_cpu_flags flags;186 acpi_status status;187 188 ACPI_FUNCTION_TRACE(ev_remove_all_sci_handlers);189 190 /* Just let the OS remove the handler and disable the level */191 192 status =193 acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,194 acpi_ev_sci_xrupt_handler);195 196 if (!acpi_gbl_sci_handler_list) {197 return (status);198 }199 200 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);201 202 /* Free all host-installed SCI handlers */203 204 while (acpi_gbl_sci_handler_list) {205 sci_handler = acpi_gbl_sci_handler_list;206 acpi_gbl_sci_handler_list = sci_handler->next;207 ACPI_FREE(sci_handler);208 }209 210 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);211 return_ACPI_STATUS(status);212}213 214#endif /* !ACPI_REDUCED_HARDWARE */215