Merge branch 'fixes-rc2' into fixes
[linux-2.6-microblaze.git] / drivers / acpi / acpica / hwgpe.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: hwgpe - Low level GPE enable/disable/clear functions
5  *
6  * Copyright (C) 2000 - 2021, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acevents.h"
13
14 #define _COMPONENT          ACPI_HARDWARE
15 ACPI_MODULE_NAME("hwgpe")
16 #if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
17 /* Local prototypes */
18 static acpi_status
19 acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
20                                 struct acpi_gpe_block_info *gpe_block,
21                                 void *context);
22
23 static acpi_status
24 acpi_hw_gpe_enable_write(u8 enable_mask,
25                          struct acpi_gpe_register_info *gpe_register_info);
26
27 /******************************************************************************
28  *
29  * FUNCTION:    acpi_hw_gpe_read
30  *
31  * PARAMETERS:  value               - Where the value is returned
32  *              reg                 - GPE register structure
33  *
34  * RETURN:      Status
35  *
36  * DESCRIPTION: Read from a GPE register in either memory or IO space.
37  *
38  * LIMITATIONS: <These limitations also apply to acpi_hw_gpe_write>
39  *      space_ID must be system_memory or system_IO.
40  *
41  ******************************************************************************/
42
43 acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
44 {
45         acpi_status status;
46         u32 value32;
47
48         if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
49 #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
50                 *value = (u64)ACPI_GET8((unsigned long)reg->address);
51                 return_ACPI_STATUS(AE_OK);
52 #else
53                 return acpi_os_read_memory((acpi_physical_address)reg->address,
54                                             value, ACPI_GPE_REGISTER_WIDTH);
55 #endif
56         }
57
58         status = acpi_os_read_port((acpi_io_address)reg->address,
59                                    &value32, ACPI_GPE_REGISTER_WIDTH);
60         if (ACPI_FAILURE(status))
61                 return_ACPI_STATUS(status);
62
63         *value = (u64)value32;
64
65         return_ACPI_STATUS(AE_OK);
66 }
67
68 /******************************************************************************
69  *
70  * FUNCTION:    acpi_hw_gpe_write
71  *
72  * PARAMETERS:  value               - Value to be written
73  *              reg                 - GPE register structure
74  *
75  * RETURN:      Status
76  *
77  * DESCRIPTION: Write to a GPE register in either memory or IO space.
78  *
79  ******************************************************************************/
80
81 acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg)
82 {
83         if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
84 #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
85                 ACPI_SET8((unsigned long)reg->address, value);
86                 return_ACPI_STATUS(AE_OK);
87 #else
88                 return acpi_os_write_memory((acpi_physical_address)reg->address,
89                                             value, ACPI_GPE_REGISTER_WIDTH);
90 #endif
91         }
92
93         return acpi_os_write_port((acpi_io_address)reg->address, (u32)value,
94                                   ACPI_GPE_REGISTER_WIDTH);
95 }
96
97 /******************************************************************************
98  *
99  * FUNCTION:    acpi_hw_get_gpe_register_bit
100  *
101  * PARAMETERS:  gpe_event_info      - Info block for the GPE
102  *
103  * RETURN:      Register mask with a one in the GPE bit position
104  *
105  * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
106  *              correct position for the input GPE.
107  *
108  ******************************************************************************/
109
110 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
111 {
112
113         return ((u32)1 <<
114                 (gpe_event_info->gpe_number -
115                  gpe_event_info->register_info->base_gpe_number));
116 }
117
118 /******************************************************************************
119  *
120  * FUNCTION:    acpi_hw_low_set_gpe
121  *
122  * PARAMETERS:  gpe_event_info      - Info block for the GPE to be disabled
123  *              action              - Enable or disable
124  *
125  * RETURN:      Status
126  *
127  * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
128  *              The enable_mask field of the involved GPE register must be
129  *              updated by the caller if necessary.
130  *
131  ******************************************************************************/
132
133 acpi_status
134 acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
135 {
136         struct acpi_gpe_register_info *gpe_register_info;
137         acpi_status status = AE_OK;
138         u64 enable_mask;
139         u32 register_bit;
140
141         ACPI_FUNCTION_ENTRY();
142
143         /* Get the info block for the entire GPE register */
144
145         gpe_register_info = gpe_event_info->register_info;
146         if (!gpe_register_info) {
147                 return (AE_NOT_EXIST);
148         }
149
150         /* Get current value of the enable register that contains this GPE */
151
152         status = acpi_hw_gpe_read(&enable_mask,
153                                   &gpe_register_info->enable_address);
154         if (ACPI_FAILURE(status)) {
155                 return (status);
156         }
157
158         /* Set or clear just the bit that corresponds to this GPE */
159
160         register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
161         switch (action) {
162         case ACPI_GPE_CONDITIONAL_ENABLE:
163
164                 /* Only enable if the corresponding enable_mask bit is set */
165
166                 if (!(register_bit & gpe_register_info->enable_mask)) {
167                         return (AE_BAD_PARAMETER);
168                 }
169
170                 ACPI_FALLTHROUGH;
171
172         case ACPI_GPE_ENABLE:
173
174                 ACPI_SET_BIT(enable_mask, register_bit);
175                 break;
176
177         case ACPI_GPE_DISABLE:
178
179                 ACPI_CLEAR_BIT(enable_mask, register_bit);
180                 break;
181
182         default:
183
184                 ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action));
185                 return (AE_BAD_PARAMETER);
186         }
187
188         if (!(register_bit & gpe_register_info->mask_for_run)) {
189
190                 /* Write the updated enable mask */
191
192                 status = acpi_hw_gpe_write(enable_mask,
193                                            &gpe_register_info->enable_address);
194         }
195         return (status);
196 }
197
198 /******************************************************************************
199  *
200  * FUNCTION:    acpi_hw_clear_gpe
201  *
202  * PARAMETERS:  gpe_event_info      - Info block for the GPE to be cleared
203  *
204  * RETURN:      Status
205  *
206  * DESCRIPTION: Clear the status bit for a single GPE.
207  *
208  ******************************************************************************/
209
210 acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info)
211 {
212         struct acpi_gpe_register_info *gpe_register_info;
213         acpi_status status;
214         u32 register_bit;
215
216         ACPI_FUNCTION_ENTRY();
217
218         /* Get the info block for the entire GPE register */
219
220         gpe_register_info = gpe_event_info->register_info;
221         if (!gpe_register_info) {
222                 return (AE_NOT_EXIST);
223         }
224
225         /*
226          * Write a one to the appropriate bit in the status register to
227          * clear this GPE.
228          */
229         register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
230
231         status = acpi_hw_gpe_write(register_bit,
232                                    &gpe_register_info->status_address);
233         return (status);
234 }
235
236 /******************************************************************************
237  *
238  * FUNCTION:    acpi_hw_get_gpe_status
239  *
240  * PARAMETERS:  gpe_event_info      - Info block for the GPE to queried
241  *              event_status        - Where the GPE status is returned
242  *
243  * RETURN:      Status
244  *
245  * DESCRIPTION: Return the status of a single GPE.
246  *
247  ******************************************************************************/
248
249 acpi_status
250 acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
251                        acpi_event_status *event_status)
252 {
253         u64 in_byte;
254         u32 register_bit;
255         struct acpi_gpe_register_info *gpe_register_info;
256         acpi_event_status local_event_status = 0;
257         acpi_status status;
258
259         ACPI_FUNCTION_ENTRY();
260
261         if (!event_status) {
262                 return (AE_BAD_PARAMETER);
263         }
264
265         /* GPE currently handled? */
266
267         if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
268             ACPI_GPE_DISPATCH_NONE) {
269                 local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER;
270         }
271
272         /* Get the info block for the entire GPE register */
273
274         gpe_register_info = gpe_event_info->register_info;
275
276         /* Get the register bitmask for this GPE */
277
278         register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
279
280         /* GPE currently enabled? (enabled for runtime?) */
281
282         if (register_bit & gpe_register_info->enable_for_run) {
283                 local_event_status |= ACPI_EVENT_FLAG_ENABLED;
284         }
285
286         /* GPE currently masked? (masked for runtime?) */
287
288         if (register_bit & gpe_register_info->mask_for_run) {
289                 local_event_status |= ACPI_EVENT_FLAG_MASKED;
290         }
291
292         /* GPE enabled for wake? */
293
294         if (register_bit & gpe_register_info->enable_for_wake) {
295                 local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
296         }
297
298         /* GPE currently enabled (enable bit == 1)? */
299
300         status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->enable_address);
301         if (ACPI_FAILURE(status)) {
302                 return (status);
303         }
304
305         if (register_bit & in_byte) {
306                 local_event_status |= ACPI_EVENT_FLAG_ENABLE_SET;
307         }
308
309         /* GPE currently active (status bit == 1)? */
310
311         status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->status_address);
312         if (ACPI_FAILURE(status)) {
313                 return (status);
314         }
315
316         if (register_bit & in_byte) {
317                 local_event_status |= ACPI_EVENT_FLAG_STATUS_SET;
318         }
319
320         /* Set return value */
321
322         (*event_status) = local_event_status;
323         return (AE_OK);
324 }
325
326 /******************************************************************************
327  *
328  * FUNCTION:    acpi_hw_gpe_enable_write
329  *
330  * PARAMETERS:  enable_mask         - Bit mask to write to the GPE register
331  *              gpe_register_info   - Gpe Register info
332  *
333  * RETURN:      Status
334  *
335  * DESCRIPTION: Write the enable mask byte to the given GPE register.
336  *
337  ******************************************************************************/
338
339 static acpi_status
340 acpi_hw_gpe_enable_write(u8 enable_mask,
341                          struct acpi_gpe_register_info *gpe_register_info)
342 {
343         acpi_status status;
344
345         gpe_register_info->enable_mask = enable_mask;
346
347         status = acpi_hw_gpe_write(enable_mask,
348                                    &gpe_register_info->enable_address);
349         return (status);
350 }
351
352 /******************************************************************************
353  *
354  * FUNCTION:    acpi_hw_disable_gpe_block
355  *
356  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
357  *              gpe_block           - Gpe Block info
358  *
359  * RETURN:      Status
360  *
361  * DESCRIPTION: Disable all GPEs within a single GPE block
362  *
363  ******************************************************************************/
364
365 acpi_status
366 acpi_hw_disable_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                 /* Disable all GPEs in this register */
377
378                 status =
379                     acpi_hw_gpe_enable_write(0x00,
380                                              &gpe_block->register_info[i]);
381                 if (ACPI_FAILURE(status)) {
382                         return (status);
383                 }
384         }
385
386         return (AE_OK);
387 }
388
389 /******************************************************************************
390  *
391  * FUNCTION:    acpi_hw_clear_gpe_block
392  *
393  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
394  *              gpe_block           - Gpe Block info
395  *
396  * RETURN:      Status
397  *
398  * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
399  *
400  ******************************************************************************/
401
402 acpi_status
403 acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
404                         struct acpi_gpe_block_info *gpe_block, void *context)
405 {
406         u32 i;
407         acpi_status status;
408
409         /* Examine each GPE Register within the block */
410
411         for (i = 0; i < gpe_block->register_count; i++) {
412
413                 /* Clear status on all GPEs in this register */
414
415                 status = acpi_hw_gpe_write(0xFF,
416                                            &gpe_block->register_info[i].status_address);
417                 if (ACPI_FAILURE(status)) {
418                         return (status);
419                 }
420         }
421
422         return (AE_OK);
423 }
424
425 /******************************************************************************
426  *
427  * FUNCTION:    acpi_hw_enable_runtime_gpe_block
428  *
429  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
430  *              gpe_block           - Gpe Block info
431  *
432  * RETURN:      Status
433  *
434  * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
435  *              combination wake/run GPEs.
436  *
437  ******************************************************************************/
438
439 acpi_status
440 acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
441                                  struct acpi_gpe_block_info *gpe_block,
442                                  void *context)
443 {
444         u32 i;
445         acpi_status status;
446         struct acpi_gpe_register_info *gpe_register_info;
447         u8 enable_mask;
448
449         /* NOTE: assumes that all GPEs are currently disabled */
450
451         /* Examine each GPE Register within the block */
452
453         for (i = 0; i < gpe_block->register_count; i++) {
454                 gpe_register_info = &gpe_block->register_info[i];
455                 if (!gpe_register_info->enable_for_run) {
456                         continue;
457                 }
458
459                 /* Enable all "runtime" GPEs in this register */
460
461                 enable_mask = gpe_register_info->enable_for_run &
462                     ~gpe_register_info->mask_for_run;
463                 status =
464                     acpi_hw_gpe_enable_write(enable_mask, gpe_register_info);
465                 if (ACPI_FAILURE(status)) {
466                         return (status);
467                 }
468         }
469
470         return (AE_OK);
471 }
472
473 /******************************************************************************
474  *
475  * FUNCTION:    acpi_hw_enable_wakeup_gpe_block
476  *
477  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
478  *              gpe_block           - Gpe Block info
479  *
480  * RETURN:      Status
481  *
482  * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
483  *              combination wake/run GPEs.
484  *
485  ******************************************************************************/
486
487 static acpi_status
488 acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
489                                 struct acpi_gpe_block_info *gpe_block,
490                                 void *context)
491 {
492         u32 i;
493         acpi_status status;
494         struct acpi_gpe_register_info *gpe_register_info;
495
496         /* Examine each GPE Register within the block */
497
498         for (i = 0; i < gpe_block->register_count; i++) {
499                 gpe_register_info = &gpe_block->register_info[i];
500
501                 /*
502                  * Enable all "wake" GPEs in this register and disable the
503                  * remaining ones.
504                  */
505
506                 status =
507                     acpi_hw_gpe_enable_write(gpe_register_info->enable_for_wake,
508                                              gpe_register_info);
509                 if (ACPI_FAILURE(status)) {
510                         return (status);
511                 }
512         }
513
514         return (AE_OK);
515 }
516
517 struct acpi_gpe_block_status_context {
518         struct acpi_gpe_register_info *gpe_skip_register_info;
519         u8 gpe_skip_mask;
520         u8 retval;
521 };
522
523 /******************************************************************************
524  *
525  * FUNCTION:    acpi_hw_get_gpe_block_status
526  *
527  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
528  *              gpe_block           - Gpe Block info
529  *              context             - GPE list walk context data
530  *
531  * RETURN:      Success
532  *
533  * DESCRIPTION: Produce a combined GPE status bits mask for the given block.
534  *
535  ******************************************************************************/
536
537 static acpi_status
538 acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
539                              struct acpi_gpe_block_info *gpe_block,
540                              void *context)
541 {
542         struct acpi_gpe_block_status_context *c = context;
543         struct acpi_gpe_register_info *gpe_register_info;
544         u64 in_enable, in_status;
545         acpi_status status;
546         u8 ret_mask;
547         u32 i;
548
549         /* Examine each GPE Register within the block */
550
551         for (i = 0; i < gpe_block->register_count; i++) {
552                 gpe_register_info = &gpe_block->register_info[i];
553
554                 status = acpi_hw_gpe_read(&in_enable,
555                                           &gpe_register_info->enable_address);
556                 if (ACPI_FAILURE(status)) {
557                         continue;
558                 }
559
560                 status = acpi_hw_gpe_read(&in_status,
561                                           &gpe_register_info->status_address);
562                 if (ACPI_FAILURE(status)) {
563                         continue;
564                 }
565
566                 ret_mask = in_enable & in_status;
567                 if (ret_mask && c->gpe_skip_register_info == gpe_register_info) {
568                         ret_mask &= ~c->gpe_skip_mask;
569                 }
570                 c->retval |= ret_mask;
571         }
572
573         return (AE_OK);
574 }
575
576 /******************************************************************************
577  *
578  * FUNCTION:    acpi_hw_disable_all_gpes
579  *
580  * PARAMETERS:  None
581  *
582  * RETURN:      Status
583  *
584  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
585  *
586  ******************************************************************************/
587
588 acpi_status acpi_hw_disable_all_gpes(void)
589 {
590         acpi_status status;
591
592         ACPI_FUNCTION_TRACE(hw_disable_all_gpes);
593
594         status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
595         return_ACPI_STATUS(status);
596 }
597
598 /******************************************************************************
599  *
600  * FUNCTION:    acpi_hw_enable_all_runtime_gpes
601  *
602  * PARAMETERS:  None
603  *
604  * RETURN:      Status
605  *
606  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
607  *
608  ******************************************************************************/
609
610 acpi_status acpi_hw_enable_all_runtime_gpes(void)
611 {
612         acpi_status status;
613
614         ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes);
615
616         status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL);
617         return_ACPI_STATUS(status);
618 }
619
620 /******************************************************************************
621  *
622  * FUNCTION:    acpi_hw_enable_all_wakeup_gpes
623  *
624  * PARAMETERS:  None
625  *
626  * RETURN:      Status
627  *
628  * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
629  *
630  ******************************************************************************/
631
632 acpi_status acpi_hw_enable_all_wakeup_gpes(void)
633 {
634         acpi_status status;
635
636         ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes);
637
638         status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
639         return_ACPI_STATUS(status);
640 }
641
642 /******************************************************************************
643  *
644  * FUNCTION:    acpi_hw_check_all_gpes
645  *
646  * PARAMETERS:  gpe_skip_device      - GPE devoce of the GPE to skip
647  *              gpe_skip_number      - Number of the GPE to skip
648  *
649  * RETURN:      Combined status of all GPEs
650  *
651  * DESCRIPTION: Check all enabled GPEs in all GPE blocks, except for the one
652  *              represented by the "skip" arguments, and return TRUE if the
653  *              status bit is set for at least one of them of FALSE otherwise.
654  *
655  ******************************************************************************/
656
657 u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number)
658 {
659         struct acpi_gpe_block_status_context context = {
660                 .gpe_skip_register_info = NULL,
661                 .retval = 0,
662         };
663         struct acpi_gpe_event_info *gpe_event_info;
664         acpi_cpu_flags flags;
665
666         ACPI_FUNCTION_TRACE(acpi_hw_check_all_gpes);
667
668         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
669
670         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_skip_device,
671                                                     gpe_skip_number);
672         if (gpe_event_info) {
673                 context.gpe_skip_register_info = gpe_event_info->register_info;
674                 context.gpe_skip_mask = acpi_hw_get_gpe_register_bit(gpe_event_info);
675         }
676
677         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
678
679         (void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &context);
680         return (context.retval != 0);
681 }
682
683 #endif                          /* !ACPI_REDUCED_HARDWARE */