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