Merge remote-tracking branch 'asoc/fix/wm5100' into tmp
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / acpi / acpica / hwgpe.c
1 /******************************************************************************
2 *
3 * Module Name: hwgpe - Low level GPE enable/disable/clear functions
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_HARDWARE
49 ACPI_MODULE_NAME("hwgpe")
50 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
51 /* Local prototypes */
52 static acpi_status
53 acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
54 struct acpi_gpe_block_info *gpe_block,
55 void *context);
56
57 /******************************************************************************
58 *
59 * FUNCTION: acpi_hw_get_gpe_register_bit
60 *
61 * PARAMETERS: gpe_event_info - Info block for the GPE
62 *
63 * RETURN: Register mask with a one in the GPE bit position
64 *
65 * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
66 * correct position for the input GPE.
67 *
68 ******************************************************************************/
69
70 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
71 {
72 return (u32)1 << (gpe_event_info->gpe_number -
73 gpe_event_info->register_info->base_gpe_number);
74 }
75
76 /******************************************************************************
77 *
78 * FUNCTION: acpi_hw_low_set_gpe
79 *
80 * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
81 * action - Enable or disable
82 *
83 * RETURN: Status
84 *
85 * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
86 *
87 ******************************************************************************/
88
89 acpi_status
90 acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
91 {
92 struct acpi_gpe_register_info *gpe_register_info;
93 acpi_status status;
94 u32 enable_mask;
95 u32 register_bit;
96
97 ACPI_FUNCTION_ENTRY();
98
99 /* Get the info block for the entire GPE register */
100
101 gpe_register_info = gpe_event_info->register_info;
102 if (!gpe_register_info) {
103 return (AE_NOT_EXIST);
104 }
105
106 /* Get current value of the enable register that contains this GPE */
107
108 status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address);
109 if (ACPI_FAILURE(status)) {
110 return (status);
111 }
112
113 /* Set or clear just the bit that corresponds to this GPE */
114
115 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
116 switch (action) {
117 case ACPI_GPE_CONDITIONAL_ENABLE:
118
119 /* Only enable if the enable_for_run bit is set */
120
121 if (!(register_bit & gpe_register_info->enable_for_run)) {
122 return (AE_BAD_PARAMETER);
123 }
124
125 /*lint -fallthrough */
126
127 case ACPI_GPE_ENABLE:
128 ACPI_SET_BIT(enable_mask, register_bit);
129 break;
130
131 case ACPI_GPE_DISABLE:
132 ACPI_CLEAR_BIT(enable_mask, register_bit);
133 break;
134
135 default:
136 ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action));
137 return (AE_BAD_PARAMETER);
138 }
139
140 /* Write the updated enable mask */
141
142 status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address);
143 return (status);
144 }
145
146 /******************************************************************************
147 *
148 * FUNCTION: acpi_hw_clear_gpe
149 *
150 * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared
151 *
152 * RETURN: Status
153 *
154 * DESCRIPTION: Clear the status bit for a single GPE.
155 *
156 ******************************************************************************/
157
158 acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
159 {
160 struct acpi_gpe_register_info *gpe_register_info;
161 acpi_status status;
162 u32 register_bit;
163
164 ACPI_FUNCTION_ENTRY();
165
166 /* Get the info block for the entire GPE register */
167
168 gpe_register_info = gpe_event_info->register_info;
169 if (!gpe_register_info) {
170 return (AE_NOT_EXIST);
171 }
172
173 /*
174 * Write a one to the appropriate bit in the status register to
175 * clear this GPE.
176 */
177 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
178
179 status = acpi_hw_write(register_bit,
180 &gpe_register_info->status_address);
181
182 return (status);
183 }
184
185 /******************************************************************************
186 *
187 * FUNCTION: acpi_hw_get_gpe_status
188 *
189 * PARAMETERS: gpe_event_info - Info block for the GPE to queried
190 * event_status - Where the GPE status is returned
191 *
192 * RETURN: Status
193 *
194 * DESCRIPTION: Return the status of a single GPE.
195 *
196 ******************************************************************************/
197
198 acpi_status
199 acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
200 acpi_event_status * event_status)
201 {
202 u32 in_byte;
203 u32 register_bit;
204 struct acpi_gpe_register_info *gpe_register_info;
205 acpi_event_status local_event_status = 0;
206 acpi_status status;
207
208 ACPI_FUNCTION_ENTRY();
209
210 if (!event_status) {
211 return (AE_BAD_PARAMETER);
212 }
213
214 /* Get the info block for the entire GPE register */
215
216 gpe_register_info = gpe_event_info->register_info;
217
218 /* Get the register bitmask for this GPE */
219
220 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
221
222 /* GPE currently enabled? (enabled for runtime?) */
223
224 if (register_bit & gpe_register_info->enable_for_run) {
225 local_event_status |= ACPI_EVENT_FLAG_ENABLED;
226 }
227
228 /* GPE enabled for wake? */
229
230 if (register_bit & gpe_register_info->enable_for_wake) {
231 local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
232 }
233
234 /* GPE currently active (status bit == 1)? */
235
236 status = acpi_hw_read(&in_byte, &gpe_register_info->status_address);
237 if (ACPI_FAILURE(status)) {
238 return (status);
239 }
240
241 if (register_bit & in_byte) {
242 local_event_status |= ACPI_EVENT_FLAG_SET;
243 }
244
245 /* Set return value */
246
247 (*event_status) = local_event_status;
248 return (AE_OK);
249 }
250
251 /******************************************************************************
252 *
253 * FUNCTION: acpi_hw_disable_gpe_block
254 *
255 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
256 * gpe_block - Gpe Block info
257 *
258 * RETURN: Status
259 *
260 * DESCRIPTION: Disable all GPEs within a single GPE block
261 *
262 ******************************************************************************/
263
264 acpi_status
265 acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
266 struct acpi_gpe_block_info *gpe_block, void *context)
267 {
268 u32 i;
269 acpi_status status;
270
271 /* Examine each GPE Register within the block */
272
273 for (i = 0; i < gpe_block->register_count; i++) {
274
275 /* Disable all GPEs in this register */
276
277 status =
278 acpi_hw_write(0x00,
279 &gpe_block->register_info[i].enable_address);
280 if (ACPI_FAILURE(status)) {
281 return (status);
282 }
283 }
284
285 return (AE_OK);
286 }
287
288 /******************************************************************************
289 *
290 * FUNCTION: acpi_hw_clear_gpe_block
291 *
292 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
293 * gpe_block - Gpe Block info
294 *
295 * RETURN: Status
296 *
297 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
298 *
299 ******************************************************************************/
300
301 acpi_status
302 acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
303 struct acpi_gpe_block_info *gpe_block, void *context)
304 {
305 u32 i;
306 acpi_status status;
307
308 /* Examine each GPE Register within the block */
309
310 for (i = 0; i < gpe_block->register_count; i++) {
311
312 /* Clear status on all GPEs in this register */
313
314 status =
315 acpi_hw_write(0xFF,
316 &gpe_block->register_info[i].status_address);
317 if (ACPI_FAILURE(status)) {
318 return (status);
319 }
320 }
321
322 return (AE_OK);
323 }
324
325 /******************************************************************************
326 *
327 * FUNCTION: acpi_hw_enable_runtime_gpe_block
328 *
329 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
330 * gpe_block - Gpe Block info
331 *
332 * RETURN: Status
333 *
334 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
335 * combination wake/run GPEs.
336 *
337 ******************************************************************************/
338
339 acpi_status
340 acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
341 struct acpi_gpe_block_info * gpe_block,
342 void *context)
343 {
344 u32 i;
345 acpi_status status;
346
347 /* NOTE: assumes that all GPEs are currently disabled */
348
349 /* Examine each GPE Register within the block */
350
351 for (i = 0; i < gpe_block->register_count; i++) {
352 if (!gpe_block->register_info[i].enable_for_run) {
353 continue;
354 }
355
356 /* Enable all "runtime" GPEs in this register */
357
358 status =
359 acpi_hw_write(gpe_block->register_info[i].enable_for_run,
360 &gpe_block->register_info[i].enable_address);
361 if (ACPI_FAILURE(status)) {
362 return (status);
363 }
364 }
365
366 return (AE_OK);
367 }
368
369 /******************************************************************************
370 *
371 * FUNCTION: acpi_hw_enable_wakeup_gpe_block
372 *
373 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
374 * gpe_block - Gpe Block info
375 *
376 * RETURN: Status
377 *
378 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
379 * combination wake/run GPEs.
380 *
381 ******************************************************************************/
382
383 static acpi_status
384 acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
385 struct acpi_gpe_block_info *gpe_block,
386 void *context)
387 {
388 u32 i;
389 acpi_status status;
390
391 /* Examine each GPE Register within the block */
392
393 for (i = 0; i < gpe_block->register_count; i++) {
394 if (!gpe_block->register_info[i].enable_for_wake) {
395 continue;
396 }
397
398 /* Enable all "wake" GPEs in this register */
399
400 status =
401 acpi_hw_write(gpe_block->register_info[i].enable_for_wake,
402 &gpe_block->register_info[i].enable_address);
403 if (ACPI_FAILURE(status)) {
404 return (status);
405 }
406 }
407
408 return (AE_OK);
409 }
410
411 /******************************************************************************
412 *
413 * FUNCTION: acpi_hw_disable_all_gpes
414 *
415 * PARAMETERS: None
416 *
417 * RETURN: Status
418 *
419 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
420 *
421 ******************************************************************************/
422
423 acpi_status acpi_hw_disable_all_gpes(void)
424 {
425 acpi_status status;
426
427 ACPI_FUNCTION_TRACE(hw_disable_all_gpes);
428
429 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
430 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
431 return_ACPI_STATUS(status);
432 }
433
434 /******************************************************************************
435 *
436 * FUNCTION: acpi_hw_enable_all_runtime_gpes
437 *
438 * PARAMETERS: None
439 *
440 * RETURN: Status
441 *
442 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
443 *
444 ******************************************************************************/
445
446 acpi_status acpi_hw_enable_all_runtime_gpes(void)
447 {
448 acpi_status status;
449
450 ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes);
451
452 status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL);
453 return_ACPI_STATUS(status);
454 }
455
456 /******************************************************************************
457 *
458 * FUNCTION: acpi_hw_enable_all_wakeup_gpes
459 *
460 * PARAMETERS: None
461 *
462 * RETURN: Status
463 *
464 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
465 *
466 ******************************************************************************/
467
468 acpi_status acpi_hw_enable_all_wakeup_gpes(void)
469 {
470 acpi_status status;
471
472 ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes);
473
474 status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
475 return_ACPI_STATUS(status);
476 }
477
478 #endif /* !ACPI_REDUCED_HARDWARE */