xref: /openbmc/linux/drivers/acpi/acpica/evsci.c (revision 95b482a8d31116f3f5c2a5089569393234d06385)
1*95b482a8SLen Brown /*******************************************************************************
2*95b482a8SLen Brown  *
3*95b482a8SLen Brown  * Module Name: evsci - System Control Interrupt configuration and
4*95b482a8SLen Brown  *                      legacy to ACPI mode state transition functions
5*95b482a8SLen Brown  *
6*95b482a8SLen Brown  ******************************************************************************/
7*95b482a8SLen Brown 
8*95b482a8SLen Brown /*
9*95b482a8SLen Brown  * Copyright (C) 2000 - 2008, Intel Corp.
10*95b482a8SLen Brown  * All rights reserved.
11*95b482a8SLen Brown  *
12*95b482a8SLen Brown  * Redistribution and use in source and binary forms, with or without
13*95b482a8SLen Brown  * modification, are permitted provided that the following conditions
14*95b482a8SLen Brown  * are met:
15*95b482a8SLen Brown  * 1. Redistributions of source code must retain the above copyright
16*95b482a8SLen Brown  *    notice, this list of conditions, and the following disclaimer,
17*95b482a8SLen Brown  *    without modification.
18*95b482a8SLen Brown  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19*95b482a8SLen Brown  *    substantially similar to the "NO WARRANTY" disclaimer below
20*95b482a8SLen Brown  *    ("Disclaimer") and any redistribution must be conditioned upon
21*95b482a8SLen Brown  *    including a substantially similar Disclaimer requirement for further
22*95b482a8SLen Brown  *    binary redistribution.
23*95b482a8SLen Brown  * 3. Neither the names of the above-listed copyright holders nor the names
24*95b482a8SLen Brown  *    of any contributors may be used to endorse or promote products derived
25*95b482a8SLen Brown  *    from this software without specific prior written permission.
26*95b482a8SLen Brown  *
27*95b482a8SLen Brown  * Alternatively, this software may be distributed under the terms of the
28*95b482a8SLen Brown  * GNU General Public License ("GPL") version 2 as published by the Free
29*95b482a8SLen Brown  * Software Foundation.
30*95b482a8SLen Brown  *
31*95b482a8SLen Brown  * NO WARRANTY
32*95b482a8SLen Brown  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*95b482a8SLen Brown  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*95b482a8SLen Brown  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35*95b482a8SLen Brown  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36*95b482a8SLen Brown  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*95b482a8SLen Brown  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*95b482a8SLen Brown  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*95b482a8SLen Brown  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*95b482a8SLen Brown  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41*95b482a8SLen Brown  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42*95b482a8SLen Brown  * POSSIBILITY OF SUCH DAMAGES.
43*95b482a8SLen Brown  */
44*95b482a8SLen Brown 
45*95b482a8SLen Brown #include <acpi/acpi.h>
46*95b482a8SLen Brown #include <acpi/accommon.h>
47*95b482a8SLen Brown #include <acpi/acevents.h>
48*95b482a8SLen Brown 
49*95b482a8SLen Brown #define _COMPONENT          ACPI_EVENTS
50*95b482a8SLen Brown ACPI_MODULE_NAME("evsci")
51*95b482a8SLen Brown 
52*95b482a8SLen Brown /* Local prototypes */
53*95b482a8SLen Brown static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context);
54*95b482a8SLen Brown 
55*95b482a8SLen Brown /*******************************************************************************
56*95b482a8SLen Brown  *
57*95b482a8SLen Brown  * FUNCTION:    acpi_ev_sci_xrupt_handler
58*95b482a8SLen Brown  *
59*95b482a8SLen Brown  * PARAMETERS:  Context   - Calling Context
60*95b482a8SLen Brown  *
61*95b482a8SLen Brown  * RETURN:      Status code indicates whether interrupt was handled.
62*95b482a8SLen Brown  *
63*95b482a8SLen Brown  * DESCRIPTION: Interrupt handler that will figure out what function or
64*95b482a8SLen Brown  *              control method to call to deal with a SCI.
65*95b482a8SLen Brown  *
66*95b482a8SLen Brown  ******************************************************************************/
67*95b482a8SLen Brown 
68*95b482a8SLen Brown static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
69*95b482a8SLen Brown {
70*95b482a8SLen Brown 	struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
71*95b482a8SLen Brown 	u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
72*95b482a8SLen Brown 
73*95b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler);
74*95b482a8SLen Brown 
75*95b482a8SLen Brown 	/*
76*95b482a8SLen Brown 	 * We are guaranteed by the ACPI CA initialization/shutdown code that
77*95b482a8SLen Brown 	 * if this interrupt handler is installed, ACPI is enabled.
78*95b482a8SLen Brown 	 */
79*95b482a8SLen Brown 
80*95b482a8SLen Brown 	/*
81*95b482a8SLen Brown 	 * Fixed Events:
82*95b482a8SLen Brown 	 * Check for and dispatch any Fixed Events that have occurred
83*95b482a8SLen Brown 	 */
84*95b482a8SLen Brown 	interrupt_handled |= acpi_ev_fixed_event_detect();
85*95b482a8SLen Brown 
86*95b482a8SLen Brown 	/*
87*95b482a8SLen Brown 	 * General Purpose Events:
88*95b482a8SLen Brown 	 * Check for and dispatch any GPEs that have occurred
89*95b482a8SLen Brown 	 */
90*95b482a8SLen Brown 	interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
91*95b482a8SLen Brown 
92*95b482a8SLen Brown 	return_UINT32(interrupt_handled);
93*95b482a8SLen Brown }
94*95b482a8SLen Brown 
95*95b482a8SLen Brown /*******************************************************************************
96*95b482a8SLen Brown  *
97*95b482a8SLen Brown  * FUNCTION:    acpi_ev_gpe_xrupt_handler
98*95b482a8SLen Brown  *
99*95b482a8SLen Brown  * PARAMETERS:  Context   - Calling Context
100*95b482a8SLen Brown  *
101*95b482a8SLen Brown  * RETURN:      Status code indicates whether interrupt was handled.
102*95b482a8SLen Brown  *
103*95b482a8SLen Brown  * DESCRIPTION: Handler for GPE Block Device interrupts
104*95b482a8SLen Brown  *
105*95b482a8SLen Brown  ******************************************************************************/
106*95b482a8SLen Brown 
107*95b482a8SLen Brown u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context)
108*95b482a8SLen Brown {
109*95b482a8SLen Brown 	struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
110*95b482a8SLen Brown 	u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
111*95b482a8SLen Brown 
112*95b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler);
113*95b482a8SLen Brown 
114*95b482a8SLen Brown 	/*
115*95b482a8SLen Brown 	 * We are guaranteed by the ACPI CA initialization/shutdown code that
116*95b482a8SLen Brown 	 * if this interrupt handler is installed, ACPI is enabled.
117*95b482a8SLen Brown 	 */
118*95b482a8SLen Brown 
119*95b482a8SLen Brown 	/* GPEs: Check for and dispatch any GPEs that have occurred */
120*95b482a8SLen Brown 
121*95b482a8SLen Brown 	interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
122*95b482a8SLen Brown 
123*95b482a8SLen Brown 	return_UINT32(interrupt_handled);
124*95b482a8SLen Brown }
125*95b482a8SLen Brown 
126*95b482a8SLen Brown /******************************************************************************
127*95b482a8SLen Brown  *
128*95b482a8SLen Brown  * FUNCTION:    acpi_ev_install_sci_handler
129*95b482a8SLen Brown  *
130*95b482a8SLen Brown  * PARAMETERS:  none
131*95b482a8SLen Brown  *
132*95b482a8SLen Brown  * RETURN:      Status
133*95b482a8SLen Brown  *
134*95b482a8SLen Brown  * DESCRIPTION: Installs SCI handler.
135*95b482a8SLen Brown  *
136*95b482a8SLen Brown  ******************************************************************************/
137*95b482a8SLen Brown 
138*95b482a8SLen Brown u32 acpi_ev_install_sci_handler(void)
139*95b482a8SLen Brown {
140*95b482a8SLen Brown 	u32 status = AE_OK;
141*95b482a8SLen Brown 
142*95b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ev_install_sci_handler);
143*95b482a8SLen Brown 
144*95b482a8SLen Brown 	status =
145*95b482a8SLen Brown 	    acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
146*95b482a8SLen Brown 					      acpi_ev_sci_xrupt_handler,
147*95b482a8SLen Brown 					      acpi_gbl_gpe_xrupt_list_head);
148*95b482a8SLen Brown 	return_ACPI_STATUS(status);
149*95b482a8SLen Brown }
150*95b482a8SLen Brown 
151*95b482a8SLen Brown /******************************************************************************
152*95b482a8SLen Brown  *
153*95b482a8SLen Brown  * FUNCTION:    acpi_ev_remove_sci_handler
154*95b482a8SLen Brown  *
155*95b482a8SLen Brown  * PARAMETERS:  none
156*95b482a8SLen Brown  *
157*95b482a8SLen Brown  * RETURN:      E_OK if handler uninstalled OK, E_ERROR if handler was not
158*95b482a8SLen Brown  *              installed to begin with
159*95b482a8SLen Brown  *
160*95b482a8SLen Brown  * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be
161*95b482a8SLen Brown  *              taken.
162*95b482a8SLen Brown  *
163*95b482a8SLen Brown  * Note:  It doesn't seem important to disable all events or set the event
164*95b482a8SLen Brown  *        enable registers to their original values. The OS should disable
165*95b482a8SLen Brown  *        the SCI interrupt level when the handler is removed, so no more
166*95b482a8SLen Brown  *        events will come in.
167*95b482a8SLen Brown  *
168*95b482a8SLen Brown  ******************************************************************************/
169*95b482a8SLen Brown 
170*95b482a8SLen Brown acpi_status acpi_ev_remove_sci_handler(void)
171*95b482a8SLen Brown {
172*95b482a8SLen Brown 	acpi_status status;
173*95b482a8SLen Brown 
174*95b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ev_remove_sci_handler);
175*95b482a8SLen Brown 
176*95b482a8SLen Brown 	/* Just let the OS remove the handler and disable the level */
177*95b482a8SLen Brown 
178*95b482a8SLen Brown 	status =
179*95b482a8SLen Brown 	    acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
180*95b482a8SLen Brown 					     acpi_ev_sci_xrupt_handler);
181*95b482a8SLen Brown 
182*95b482a8SLen Brown 	return_ACPI_STATUS(status);
183*95b482a8SLen Brown }
184