Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
evevent.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: evevent - Fixed Event handling and dispatch
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  * notice, this list of conditions, and the following disclaimer,
16  * without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  * substantially similar to the "NO WARRANTY" disclaimer below
19  * ("Disclaimer") and any redistribution must be conditioned upon
20  * including a substantially similar Disclaimer requirement for further
21  * binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  * of any contributors may be used to endorse or promote products derived
24  * from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acevents.h"
47 
48 #define _COMPONENT ACPI_EVENTS
49 ACPI_MODULE_NAME("evevent")
50 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
51 /* Local prototypes */
52 static acpi_status acpi_ev_fixed_event_initialize(void);
53 
54 static u32 acpi_ev_fixed_event_dispatch(u32 event);
55 
56 /*******************************************************************************
57  *
58  * FUNCTION: acpi_ev_initialize_events
59  *
60  * PARAMETERS: None
61  *
62  * RETURN: Status
63  *
64  * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
65  *
66  ******************************************************************************/
67 
69 {
71 
72  ACPI_FUNCTION_TRACE(ev_initialize_events);
73 
74  /* If Hardware Reduced flag is set, there are no fixed events */
75 
78  }
79 
80  /*
81  * Initialize the Fixed and General Purpose Events. This is done prior to
82  * enabling SCIs to prevent interrupts from occurring before the handlers
83  * are installed.
84  */
85  status = acpi_ev_fixed_event_initialize();
86  if (ACPI_FAILURE(status)) {
87  ACPI_EXCEPTION((AE_INFO, status,
88  "Unable to initialize fixed events"));
89  return_ACPI_STATUS(status);
90  }
91 
92  status = acpi_ev_gpe_initialize();
93  if (ACPI_FAILURE(status)) {
94  ACPI_EXCEPTION((AE_INFO, status,
95  "Unable to initialize general purpose events"));
96  return_ACPI_STATUS(status);
97  }
98 
99  return_ACPI_STATUS(status);
100 }
101 
102 /*******************************************************************************
103  *
104  * FUNCTION: acpi_ev_install_xrupt_handlers
105  *
106  * PARAMETERS: None
107  *
108  * RETURN: Status
109  *
110  * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
111  *
112  ******************************************************************************/
113 
115 {
117 
118  ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers);
119 
120  /* If Hardware Reduced flag is set, there is no ACPI h/w */
121 
124  }
125 
126  /* Install the SCI handler */
127 
128  status = acpi_ev_install_sci_handler();
129  if (ACPI_FAILURE(status)) {
130  ACPI_EXCEPTION((AE_INFO, status,
131  "Unable to install System Control Interrupt handler"));
132  return_ACPI_STATUS(status);
133  }
134 
135  /* Install the handler for the Global Lock */
136 
138  if (ACPI_FAILURE(status)) {
139  ACPI_EXCEPTION((AE_INFO, status,
140  "Unable to initialize Global Lock handler"));
141  return_ACPI_STATUS(status);
142  }
143 
145  return_ACPI_STATUS(status);
146 }
147 
148 /*******************************************************************************
149  *
150  * FUNCTION: acpi_ev_fixed_event_initialize
151  *
152  * PARAMETERS: None
153  *
154  * RETURN: Status
155  *
156  * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
157  *
158  ******************************************************************************/
159 
160 static acpi_status acpi_ev_fixed_event_initialize(void)
161 {
162  u32 i;
164 
165  /*
166  * Initialize the structure that keeps track of fixed event handlers and
167  * enable the fixed events.
168  */
169  for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
172 
173  /* Disable the fixed event */
174 
175  if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
176  status =
178  [i].enable_register_id,
180  if (ACPI_FAILURE(status)) {
181  return (status);
182  }
183  }
184  }
185 
186  return (AE_OK);
187 }
188 
189 /*******************************************************************************
190  *
191  * FUNCTION: acpi_ev_fixed_event_detect
192  *
193  * PARAMETERS: None
194  *
195  * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
196  *
197  * DESCRIPTION: Checks the PM status register for active fixed events
198  *
199  ******************************************************************************/
200 
202 {
204  u32 fixed_status;
205  u32 fixed_enable;
206  u32 i;
207 
208  ACPI_FUNCTION_NAME(ev_fixed_event_detect);
209 
210  /*
211  * Read the fixed feature status and enable registers, as all the cases
212  * depend on their values. Ignore errors here.
213  */
216 
218  "Fixed Event Block: Enable %08X Status %08X\n",
219  fixed_enable, fixed_status));
220 
221  /*
222  * Check for all possible Fixed Events and dispatch those that are active
223  */
224  for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
225 
226  /* Both the status and enable bits must be on for this event */
227 
228  if ((fixed_status & acpi_gbl_fixed_event_info[i].
229  status_bit_mask)
230  && (fixed_enable & acpi_gbl_fixed_event_info[i].
231  enable_bit_mask)) {
232  /*
233  * Found an active (signalled) event. Invoke global event
234  * handler if present.
235  */
241  }
242 
243  int_status |= acpi_ev_fixed_event_dispatch(i);
244  }
245  }
246 
247  return (int_status);
248 }
249 
250 /*******************************************************************************
251  *
252  * FUNCTION: acpi_ev_fixed_event_dispatch
253  *
254  * PARAMETERS: event - Event type
255  *
256  * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
257  *
258  * DESCRIPTION: Clears the status bit for the requested event, calls the
259  * handler that previously registered for the event.
260  *
261  ******************************************************************************/
262 
263 static u32 acpi_ev_fixed_event_dispatch(u32 event)
264 {
265 
267 
268  /* Clear the status bit */
269 
271  status_register_id, ACPI_CLEAR_STATUS);
272 
273  /*
274  * Make sure we've got a handler. If not, report an error. The event is
275  * disabled to prevent further interrupts.
276  */
277  if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
279  enable_register_id,
281 
283  "No installed handler for fixed event [0x%08X]",
284  event));
285 
287  }
288 
289  /* Invoke the Fixed Event handler */
290 
291  return ((acpi_gbl_fixed_event_handlers[event].
292  handler) (acpi_gbl_fixed_event_handlers[event].context));
293 }
294 
295 #endif /* !ACPI_REDUCED_HARDWARE */