167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: evsci - System Control Interrupt configuration and
467754Smsmith *                      legacy to ACPI mode state transition functions
567754Smsmith *
667754Smsmith ******************************************************************************/
767754Smsmith
8217365Sjkim/*
9306536Sjkim * Copyright (C) 2000 - 2016, 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,
221306536Sjkim        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,
260306536Sjkim        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