ACPICA: GPE support: Remove extraneous parameter from low-level function.
[firefly-linux-kernel-4.4.55.git] / drivers / acpi / acpica / hwgpe.c
1
2 /******************************************************************************
3  *
4  * Module Name: hwgpe - Low level GPE enable/disable/clear functions
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2012, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "acevents.h"
48
49 #define _COMPONENT          ACPI_HARDWARE
50 ACPI_MODULE_NAME("hwgpe")
51 #if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
52 /* Local prototypes */
53 static acpi_status
54 acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
55                                 struct acpi_gpe_block_info *gpe_block,
56                                 void *context);
57
58 /******************************************************************************
59  *
60  * FUNCTION:    acpi_hw_get_gpe_register_bit
61  *
62  * PARAMETERS:  gpe_event_info      - Info block for the GPE
63  *
64  * RETURN:      Register mask with a one in the GPE bit position
65  *
66  * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
67  *              correct position for the input GPE.
68  *
69  ******************************************************************************/
70
71 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
72 {
73         return (u32)1 << (gpe_event_info->gpe_number -
74                  gpe_event_info->register_info->base_gpe_number);
75 }
76
77 /******************************************************************************
78  *
79  * FUNCTION:    acpi_hw_low_set_gpe
80  *
81  * PARAMETERS:  gpe_event_info      - Info block for the GPE to be disabled
82  *              action              - Enable or disable
83  *
84  * RETURN:      Status
85  *
86  * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
87  *
88  ******************************************************************************/
89
90 acpi_status
91 acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
92 {
93         struct acpi_gpe_register_info *gpe_register_info;
94         acpi_status status;
95         u32 enable_mask;
96         u32 register_bit;
97
98         ACPI_FUNCTION_ENTRY();
99
100         /* Get the info block for the entire GPE register */
101
102         gpe_register_info = gpe_event_info->register_info;
103         if (!gpe_register_info) {
104                 return (AE_NOT_EXIST);
105         }
106
107         /* Get current value of the enable register that contains this GPE */
108
109         status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address);
110         if (ACPI_FAILURE(status)) {
111                 return (status);
112         }
113
114         /* Set or clear just the bit that corresponds to this GPE */
115
116         register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
117         switch (action) {
118         case ACPI_GPE_CONDITIONAL_ENABLE:
119
120                 /* Only enable if the enable_for_run bit is set */
121
122                 if (!(register_bit & gpe_register_info->enable_for_run)) {
123                         return (AE_BAD_PARAMETER);
124                 }
125
126                 /*lint -fallthrough */
127
128         case ACPI_GPE_ENABLE:
129                 ACPI_SET_BIT(enable_mask, register_bit);
130                 break;
131
132         case ACPI_GPE_DISABLE:
133                 ACPI_CLEAR_BIT(enable_mask, register_bit);
134                 break;
135
136         default:
137                 ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action));
138                 return (AE_BAD_PARAMETER);
139         }
140
141         /* Write the updated enable mask */
142
143         status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address);
144         return (status);
145 }
146
147 /******************************************************************************
148  *
149  * FUNCTION:    acpi_hw_clear_gpe
150  *
151  * PARAMETERS:  gpe_event_info      - Info block for the GPE to be cleared
152  *
153  * RETURN:      Status
154  *
155  * DESCRIPTION: Clear the status bit for a single GPE.
156  *
157  ******************************************************************************/
158
159 acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
160 {
161         struct acpi_gpe_register_info *gpe_register_info;
162         acpi_status status;
163         u32 register_bit;
164
165         ACPI_FUNCTION_ENTRY();
166
167         /* Get the info block for the entire GPE register */
168
169         gpe_register_info = gpe_event_info->register_info;
170         if (!gpe_register_info) {
171                 return (AE_NOT_EXIST);
172         }
173
174         /*
175          * Write a one to the appropriate bit in the status register to
176          * clear this GPE.
177          */
178         register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
179
180         status = acpi_hw_write(register_bit,
181                                &gpe_register_info->status_address);
182
183         return (status);
184 }
185
186 /******************************************************************************
187  *
188  * FUNCTION:    acpi_hw_get_gpe_status
189  *
190  * PARAMETERS:  gpe_event_info      - Info block for the GPE to queried
191  *              event_status        - Where the GPE status is returned
192  *
193  * RETURN:      Status
194  *
195  * DESCRIPTION: Return the status of a single GPE.
196  *
197  ******************************************************************************/
198
199 acpi_status
200 acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
201                        acpi_event_status * event_status)
202 {
203         u32 in_byte;
204         u32 register_bit;
205         struct acpi_gpe_register_info *gpe_register_info;
206         acpi_event_status local_event_status = 0;
207         acpi_status status;
208
209         ACPI_FUNCTION_ENTRY();
210
211         if (!event_status) {
212                 return (AE_BAD_PARAMETER);
213         }
214
215         /* Get the info block for the entire GPE register */
216
217         gpe_register_info = gpe_event_info->register_info;
218
219         /* Get the register bitmask for this GPE */
220
221         register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
222
223         /* GPE currently enabled? (enabled for runtime?) */
224
225         if (register_bit & gpe_register_info->enable_for_run) {
226                 local_event_status |= ACPI_EVENT_FLAG_ENABLED;
227         }
228
229         /* GPE enabled for wake? */
230
231         if (register_bit & gpe_register_info->enable_for_wake) {
232                 local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
233         }
234
235         /* GPE currently active (status bit == 1)? */
236
237         status = acpi_hw_read(&in_byte, &gpe_register_info->status_address);
238         if (ACPI_FAILURE(status)) {
239                 return (status);
240         }
241
242         if (register_bit & in_byte) {
243                 local_event_status |= ACPI_EVENT_FLAG_SET;
244         }
245
246         /* Set return value */
247
248         (*event_status) = local_event_status;
249         return (AE_OK);
250 }
251
252 /******************************************************************************
253  *
254  * FUNCTION:    acpi_hw_disable_gpe_block
255  *
256  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
257  *              gpe_block           - Gpe Block info
258  *
259  * RETURN:      Status
260  *
261  * DESCRIPTION: Disable all GPEs within a single GPE block
262  *
263  ******************************************************************************/
264
265 acpi_status
266 acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
267                           struct acpi_gpe_block_info *gpe_block, void *context)
268 {
269         u32 i;
270         acpi_status status;
271
272         /* Examine each GPE Register within the block */
273
274         for (i = 0; i < gpe_block->register_count; i++) {
275
276                 /* Disable all GPEs in this register */
277
278                 status =
279                     acpi_hw_write(0x00,
280                                   &gpe_block->register_info[i].enable_address);
281                 if (ACPI_FAILURE(status)) {
282                         return (status);
283                 }
284         }
285
286         return (AE_OK);
287 }
288
289 /******************************************************************************
290  *
291  * FUNCTION:    acpi_hw_clear_gpe_block
292  *
293  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
294  *              gpe_block           - Gpe Block info
295  *
296  * RETURN:      Status
297  *
298  * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
299  *
300  ******************************************************************************/
301
302 acpi_status
303 acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
304                         struct acpi_gpe_block_info *gpe_block, void *context)
305 {
306         u32 i;
307         acpi_status status;
308
309         /* Examine each GPE Register within the block */
310
311         for (i = 0; i < gpe_block->register_count; i++) {
312
313                 /* Clear status on all GPEs in this register */
314
315                 status =
316                     acpi_hw_write(0xFF,
317                                   &gpe_block->register_info[i].status_address);
318                 if (ACPI_FAILURE(status)) {
319                         return (status);
320                 }
321         }
322
323         return (AE_OK);
324 }
325
326 /******************************************************************************
327  *
328  * FUNCTION:    acpi_hw_enable_runtime_gpe_block
329  *
330  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
331  *              gpe_block           - Gpe Block info
332  *
333  * RETURN:      Status
334  *
335  * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
336  *              combination wake/run GPEs.
337  *
338  ******************************************************************************/
339
340 acpi_status
341 acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
342                                  struct acpi_gpe_block_info *gpe_block, 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 */