branch update for HEAD-2003091401
[reactos.git] / drivers / bus / acpi / events / evsci.c
1 /*******************************************************************************
2  *
3  * Module Name: evsci - System Control Interrupt configuration and
4  *                      legacy to ACPI mode state transition functions
5  *              $Revision$
6  *
7  ******************************************************************************/
8
9 /*
10  *  Copyright (C) 2000, 2001 R. Byron Moore
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27 #include "acpi.h"
28 #include "acnamesp.h"
29 #include "achware.h"
30 #include "acevents.h"
31
32
33 #define _COMPONENT          ACPI_EVENTS
34          MODULE_NAME         ("evsci")
35
36
37 /*
38  * Elements correspond to counts for TMR, NOT_USED, GBL, PWR_BTN, SLP_BTN, RTC,
39  * and GENERAL respectively.  These counts are modified by the ACPI interrupt
40  * handler.
41  *
42  * TBD: [Investigate] Note that GENERAL should probably be split out into
43  * one element for each bit in the GPE registers
44  */
45
46
47 /*******************************************************************************
48  *
49  * FUNCTION:    Acpi_ev_sci_handler
50  *
51  * PARAMETERS:  Context   - Calling Context
52  *
53  * RETURN:      Status code indicates whether interrupt was handled.
54  *
55  * DESCRIPTION: Interrupt handler that will figure out what function or
56  *              control method to call to deal with a SCI.  Installed
57  *              using BU interrupt support.
58  *
59  ******************************************************************************/
60
61 static u32
62 acpi_ev_sci_handler (void *context)
63 {
64         u32                     interrupt_handled = INTERRUPT_NOT_HANDLED;
65
66
67         /*
68          * Make sure that ACPI is enabled by checking SCI_EN.  Note that we are
69          * required to treat the SCI interrupt as sharable, level, active low.
70          */
71         if (!acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) {
72                 /* ACPI is not enabled;  this interrupt cannot be for us */
73
74                 return (INTERRUPT_NOT_HANDLED);
75         }
76
77         /*
78          * Fixed Acpi_events:
79          * -------------
80          * Check for and dispatch any Fixed Acpi_events that have occurred
81          */
82         interrupt_handled |= acpi_ev_fixed_event_detect ();
83
84         /*
85          * GPEs:
86          * -----
87          * Check for and dispatch any GPEs that have occurred
88          */
89         interrupt_handled |= acpi_ev_gpe_detect ();
90
91         return (interrupt_handled);
92 }
93
94
95 /******************************************************************************
96  *
97  * FUNCTION:    Acpi_ev_install_sci_handler
98  *
99  * PARAMETERS:  none
100  *
101  * RETURN:      Status
102  *
103  * DESCRIPTION: Installs SCI handler.
104  *
105  ******************************************************************************/
106
107 u32
108 acpi_ev_install_sci_handler (void)
109 {
110         u32                     except = AE_OK;
111
112
113         except = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
114                           acpi_ev_sci_handler,
115                           NULL);
116
117         return (except);
118 }
119
120
121 /******************************************************************************
122
123  *
124  * FUNCTION:    Acpi_ev_remove_sci_handler
125  *
126  * PARAMETERS:  none
127  *
128  * RETURN:      E_OK if handler uninstalled OK, E_ERROR if handler was not
129  *              installed to begin with
130  *
131  * DESCRIPTION: Restores original status of all fixed event enable bits and
132  *              removes SCI handler.
133  *
134  ******************************************************************************/
135
136 ACPI_STATUS
137 acpi_ev_remove_sci_handler (void)
138 {
139 #if 0
140         /* TBD:[Investigate] Figure this out!!  Disable all events first ???  */
141
142         if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (TMR_FIXED_EVENT)) {
143                 acpi_event_disable_event (TMR_FIXED_EVENT);
144         }
145
146         if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (GBL_FIXED_EVENT)) {
147                 acpi_event_disable_event (GBL_FIXED_EVENT);
148         }
149
150         if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (PWR_BTN_FIXED_EVENT)) {
151                 acpi_event_disable_event (PWR_BTN_FIXED_EVENT);
152         }
153
154         if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (SLP_BTN_FIXED_EVENT)) {
155                 acpi_event_disable_event (SLP_BTN_FIXED_EVENT);
156         }
157
158         if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (RTC_FIXED_EVENT)) {
159                 acpi_event_disable_event (RTC_FIXED_EVENT);
160         }
161
162         original_fixed_enable_bit_status = 0;
163
164 #endif
165
166         acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
167                            acpi_ev_sci_handler);
168
169         return (AE_OK);
170 }
171
172
173 /*******************************************************************************
174  *
175  * FUNCTION:    Acpi_ev_restore_acpi_state
176  *
177  * PARAMETERS:  none
178  *
179  * RETURN:      none
180  *
181  * DESCRIPTION: Restore the original ACPI state of the machine
182  *
183  ******************************************************************************/
184
185 void
186 acpi_ev_restore_acpi_state (void)
187 {
188         u32                     index;
189
190
191         /* Restore the state of the chipset enable bits. */
192
193         if (acpi_gbl_restore_acpi_chipset == TRUE) {
194                 /* Restore the fixed events */
195
196                 if (acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN) !=
197                                 acpi_gbl_pm1_enable_register_save) {
198                         acpi_hw_register_write (ACPI_MTX_LOCK, PM1_EN,
199                                 acpi_gbl_pm1_enable_register_save);
200                 }
201
202
203                 /* Ensure that all status bits are clear */
204
205                 acpi_hw_clear_acpi_status ();
206
207
208                 /* Now restore the GPEs */
209
210                 for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) {
211                         if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index) !=
212                                         acpi_gbl_gpe0enable_register_save[index]) {
213                                 acpi_hw_register_write (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index,
214                                         acpi_gbl_gpe0enable_register_save[index]);
215                         }
216                 }
217
218                 /* GPE 1 present? */
219
220                 if (acpi_gbl_FADT->gpe1_blk_len) {
221                         for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) {
222                                 if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index) !=
223                                         acpi_gbl_gpe1_enable_register_save[index]) {
224                                         acpi_hw_register_write (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index,
225                                                 acpi_gbl_gpe1_enable_register_save[index]);
226                                 }
227                         }
228                 }
229
230                 if (acpi_hw_get_mode() != acpi_gbl_original_mode) {
231                         acpi_hw_set_mode (acpi_gbl_original_mode);
232                 }
233         }
234
235         return;
236 }
237
238
239 /******************************************************************************
240  *
241  * FUNCTION:    Acpi_ev_terminate
242  *
243  * PARAMETERS:  none
244  *
245  * RETURN:      none
246  *
247  * DESCRIPTION: free memory allocated for table storage.
248  *
249  ******************************************************************************/
250
251 void
252 acpi_ev_terminate (void)
253 {
254
255
256         /*
257          * Free global tables, etc.
258          */
259
260         if (acpi_gbl_gpe_registers) {
261                 acpi_cm_free (acpi_gbl_gpe_registers);
262         }
263
264         if (acpi_gbl_gpe_info) {
265                 acpi_cm_free (acpi_gbl_gpe_info);
266         }
267
268         return;
269 }
270
271