Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: evsci - System Control Interrupt configuration and
0005  *                      legacy to ACPI mode state transition functions
0006  *
0007  ******************************************************************************/
0008 
0009 #include <acpi/acpi.h>
0010 #include "accommon.h"
0011 #include "acevents.h"
0012 
0013 #define _COMPONENT          ACPI_EVENTS
0014 ACPI_MODULE_NAME("evsci")
0015 #if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
0016 /* Local prototypes */
0017 static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context);
0018 
0019 /*******************************************************************************
0020  *
0021  * FUNCTION:    acpi_ev_sci_dispatch
0022  *
0023  * PARAMETERS:  None
0024  *
0025  * RETURN:      Status code indicates whether interrupt was handled.
0026  *
0027  * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers.
0028  *
0029  ******************************************************************************/
0030 
0031 u32 acpi_ev_sci_dispatch(void)
0032 {
0033     struct acpi_sci_handler_info *sci_handler;
0034     acpi_cpu_flags flags;
0035     u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
0036 
0037     ACPI_FUNCTION_NAME(ev_sci_dispatch);
0038 
0039     /* Are there any host-installed SCI handlers? */
0040 
0041     if (!acpi_gbl_sci_handler_list) {
0042         return (int_status);
0043     }
0044 
0045     flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
0046 
0047     /* Invoke all host-installed SCI handlers */
0048 
0049     sci_handler = acpi_gbl_sci_handler_list;
0050     while (sci_handler) {
0051 
0052         /* Invoke the installed handler (at interrupt level) */
0053 
0054         int_status |= sci_handler->address(sci_handler->context);
0055 
0056         sci_handler = sci_handler->next;
0057     }
0058 
0059     acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0060     return (int_status);
0061 }
0062 
0063 /*******************************************************************************
0064  *
0065  * FUNCTION:    acpi_ev_sci_xrupt_handler
0066  *
0067  * PARAMETERS:  context   - Calling Context
0068  *
0069  * RETURN:      Status code indicates whether interrupt was handled.
0070  *
0071  * DESCRIPTION: Interrupt handler that will figure out what function or
0072  *              control method to call to deal with a SCI.
0073  *
0074  ******************************************************************************/
0075 
0076 static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
0077 {
0078     struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
0079     u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
0080 
0081     ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler);
0082 
0083     /*
0084      * We are guaranteed by the ACPICA initialization/shutdown code that
0085      * if this interrupt handler is installed, ACPI is enabled.
0086      */
0087 
0088     /*
0089      * Fixed Events:
0090      * Check for and dispatch any Fixed Events that have occurred
0091      */
0092     interrupt_handled |= acpi_ev_fixed_event_detect();
0093 
0094     /*
0095      * General Purpose Events:
0096      * Check for and dispatch any GPEs that have occurred
0097      */
0098     interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
0099 
0100     /* Invoke all host-installed SCI handlers */
0101 
0102     interrupt_handled |= acpi_ev_sci_dispatch();
0103 
0104     acpi_sci_count++;
0105     return_UINT32(interrupt_handled);
0106 }
0107 
0108 /*******************************************************************************
0109  *
0110  * FUNCTION:    acpi_ev_gpe_xrupt_handler
0111  *
0112  * PARAMETERS:  context   - Calling Context
0113  *
0114  * RETURN:      Status code indicates whether interrupt was handled.
0115  *
0116  * DESCRIPTION: Handler for GPE Block Device interrupts
0117  *
0118  ******************************************************************************/
0119 
0120 u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context)
0121 {
0122     struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
0123     u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
0124 
0125     ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler);
0126 
0127     /*
0128      * We are guaranteed by the ACPICA initialization/shutdown code that
0129      * if this interrupt handler is installed, ACPI is enabled.
0130      */
0131 
0132     /* GPEs: Check for and dispatch any GPEs that have occurred */
0133 
0134     interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
0135     return_UINT32(interrupt_handled);
0136 }
0137 
0138 /******************************************************************************
0139  *
0140  * FUNCTION:    acpi_ev_install_sci_handler
0141  *
0142  * PARAMETERS:  none
0143  *
0144  * RETURN:      Status
0145  *
0146  * DESCRIPTION: Installs SCI handler.
0147  *
0148  ******************************************************************************/
0149 
0150 u32 acpi_ev_install_sci_handler(void)
0151 {
0152     u32 status = AE_OK;
0153 
0154     ACPI_FUNCTION_TRACE(ev_install_sci_handler);
0155 
0156     status =
0157         acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
0158                           acpi_ev_sci_xrupt_handler,
0159                           acpi_gbl_gpe_xrupt_list_head);
0160     return_ACPI_STATUS(status);
0161 }
0162 
0163 /******************************************************************************
0164  *
0165  * FUNCTION:    acpi_ev_remove_all_sci_handlers
0166  *
0167  * PARAMETERS:  none
0168  *
0169  * RETURN:      AE_OK if handler uninstalled, AE_ERROR if handler was not
0170  *              installed to begin with
0171  *
0172  * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be
0173  *              taken. Remove all host-installed SCI handlers.
0174  *
0175  * Note:  It doesn't seem important to disable all events or set the event
0176  *        enable registers to their original values. The OS should disable
0177  *        the SCI interrupt level when the handler is removed, so no more
0178  *        events will come in.
0179  *
0180  ******************************************************************************/
0181 
0182 acpi_status acpi_ev_remove_all_sci_handlers(void)
0183 {
0184     struct acpi_sci_handler_info *sci_handler;
0185     acpi_cpu_flags flags;
0186     acpi_status status;
0187 
0188     ACPI_FUNCTION_TRACE(ev_remove_all_sci_handlers);
0189 
0190     /* Just let the OS remove the handler and disable the level */
0191 
0192     status =
0193         acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
0194                          acpi_ev_sci_xrupt_handler);
0195 
0196     if (!acpi_gbl_sci_handler_list) {
0197         return (status);
0198     }
0199 
0200     flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
0201 
0202     /* Free all host-installed SCI handlers */
0203 
0204     while (acpi_gbl_sci_handler_list) {
0205         sci_handler = acpi_gbl_sci_handler_list;
0206         acpi_gbl_sci_handler_list = sci_handler->next;
0207         ACPI_FREE(sci_handler);
0208     }
0209 
0210     acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0211     return_ACPI_STATUS(status);
0212 }
0213 
0214 #endif              /* !ACPI_REDUCED_HARDWARE */