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