This source file includes following definitions.
- ACPI_MODULE_NAME
- acpi_hw_low_set_gpe
- acpi_hw_clear_gpe
- acpi_hw_get_gpe_status
- acpi_hw_gpe_enable_write
- acpi_hw_disable_gpe_block
- acpi_hw_clear_gpe_block
- acpi_hw_enable_runtime_gpe_block
- acpi_hw_enable_wakeup_gpe_block
- acpi_hw_get_gpe_block_status
- acpi_hw_disable_all_gpes
- acpi_hw_enable_all_runtime_gpes
- acpi_hw_enable_all_wakeup_gpes
- acpi_hw_check_all_gpes
1
2
3
4
5
6
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)
17
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
30
31
32
33
34
35
36
37
38
39
40 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
41 {
42
43 return ((u32)1 <<
44 (gpe_event_info->gpe_number -
45 gpe_event_info->register_info->base_gpe_number));
46 }
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 acpi_status
64 acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
65 {
66 struct acpi_gpe_register_info *gpe_register_info;
67 acpi_status status = AE_OK;
68 u64 enable_mask;
69 u32 register_bit;
70
71 ACPI_FUNCTION_ENTRY();
72
73
74
75 gpe_register_info = gpe_event_info->register_info;
76 if (!gpe_register_info) {
77 return (AE_NOT_EXIST);
78 }
79
80
81
82 status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address);
83 if (ACPI_FAILURE(status)) {
84 return (status);
85 }
86
87
88
89 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
90 switch (action) {
91 case ACPI_GPE_CONDITIONAL_ENABLE:
92
93
94
95 if (!(register_bit & gpe_register_info->enable_mask)) {
96 return (AE_BAD_PARAMETER);
97 }
98
99
100
101 case ACPI_GPE_ENABLE:
102
103 ACPI_SET_BIT(enable_mask, register_bit);
104 break;
105
106 case ACPI_GPE_DISABLE:
107
108 ACPI_CLEAR_BIT(enable_mask, register_bit);
109 break;
110
111 default:
112
113 ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action));
114 return (AE_BAD_PARAMETER);
115 }
116
117 if (!(register_bit & gpe_register_info->mask_for_run)) {
118
119
120
121 status =
122 acpi_hw_write(enable_mask,
123 &gpe_register_info->enable_address);
124 }
125 return (status);
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140 acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info)
141 {
142 struct acpi_gpe_register_info *gpe_register_info;
143 acpi_status status;
144 u32 register_bit;
145
146 ACPI_FUNCTION_ENTRY();
147
148
149
150 gpe_register_info = gpe_event_info->register_info;
151 if (!gpe_register_info) {
152 return (AE_NOT_EXIST);
153 }
154
155
156
157
158
159 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
160
161 status =
162 acpi_hw_write(register_bit, &gpe_register_info->status_address);
163 return (status);
164 }
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179 acpi_status
180 acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
181 acpi_event_status *event_status)
182 {
183 u64 in_byte;
184 u32 register_bit;
185 struct acpi_gpe_register_info *gpe_register_info;
186 acpi_event_status local_event_status = 0;
187 acpi_status status;
188
189 ACPI_FUNCTION_ENTRY();
190
191 if (!event_status) {
192 return (AE_BAD_PARAMETER);
193 }
194
195
196
197 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
198 ACPI_GPE_DISPATCH_NONE) {
199 local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER;
200 }
201
202
203
204 gpe_register_info = gpe_event_info->register_info;
205
206
207
208 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
209
210
211
212 if (register_bit & gpe_register_info->enable_for_run) {
213 local_event_status |= ACPI_EVENT_FLAG_ENABLED;
214 }
215
216
217
218 if (register_bit & gpe_register_info->mask_for_run) {
219 local_event_status |= ACPI_EVENT_FLAG_MASKED;
220 }
221
222
223
224 if (register_bit & gpe_register_info->enable_for_wake) {
225 local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
226 }
227
228
229
230 status = acpi_hw_read(&in_byte, &gpe_register_info->enable_address);
231 if (ACPI_FAILURE(status)) {
232 return (status);
233 }
234
235 if (register_bit & in_byte) {
236 local_event_status |= ACPI_EVENT_FLAG_ENABLE_SET;
237 }
238
239
240
241 status = acpi_hw_read(&in_byte, &gpe_register_info->status_address);
242 if (ACPI_FAILURE(status)) {
243 return (status);
244 }
245
246 if (register_bit & in_byte) {
247 local_event_status |= ACPI_EVENT_FLAG_STATUS_SET;
248 }
249
250
251
252 (*event_status) = local_event_status;
253 return (AE_OK);
254 }
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 static acpi_status
270 acpi_hw_gpe_enable_write(u8 enable_mask,
271 struct acpi_gpe_register_info *gpe_register_info)
272 {
273 acpi_status status;
274
275 gpe_register_info->enable_mask = enable_mask;
276
277 status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address);
278 return (status);
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294 acpi_status
295 acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
296 struct acpi_gpe_block_info *gpe_block, void *context)
297 {
298 u32 i;
299 acpi_status status;
300
301
302
303 for (i = 0; i < gpe_block->register_count; i++) {
304
305
306
307 status =
308 acpi_hw_gpe_enable_write(0x00,
309 &gpe_block->register_info[i]);
310 if (ACPI_FAILURE(status)) {
311 return (status);
312 }
313 }
314
315 return (AE_OK);
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 acpi_status
332 acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
333 struct acpi_gpe_block_info *gpe_block, void *context)
334 {
335 u32 i;
336 acpi_status status;
337
338
339
340 for (i = 0; i < gpe_block->register_count; i++) {
341
342
343
344 status =
345 acpi_hw_write(0xFF,
346 &gpe_block->register_info[i].status_address);
347 if (ACPI_FAILURE(status)) {
348 return (status);
349 }
350 }
351
352 return (AE_OK);
353 }
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369 acpi_status
370 acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
371 struct acpi_gpe_block_info *gpe_block,
372 void *context)
373 {
374 u32 i;
375 acpi_status status;
376 struct acpi_gpe_register_info *gpe_register_info;
377 u8 enable_mask;
378
379
380
381
382
383 for (i = 0; i < gpe_block->register_count; i++) {
384 gpe_register_info = &gpe_block->register_info[i];
385 if (!gpe_register_info->enable_for_run) {
386 continue;
387 }
388
389
390
391 enable_mask = gpe_register_info->enable_for_run &
392 ~gpe_register_info->mask_for_run;
393 status =
394 acpi_hw_gpe_enable_write(enable_mask, gpe_register_info);
395 if (ACPI_FAILURE(status)) {
396 return (status);
397 }
398 }
399
400 return (AE_OK);
401 }
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417 static acpi_status
418 acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
419 struct acpi_gpe_block_info *gpe_block,
420 void *context)
421 {
422 u32 i;
423 acpi_status status;
424 struct acpi_gpe_register_info *gpe_register_info;
425
426
427
428 for (i = 0; i < gpe_block->register_count; i++) {
429 gpe_register_info = &gpe_block->register_info[i];
430
431
432
433
434
435
436 status =
437 acpi_hw_gpe_enable_write(gpe_register_info->enable_for_wake,
438 gpe_register_info);
439 if (ACPI_FAILURE(status)) {
440 return (status);
441 }
442 }
443
444 return (AE_OK);
445 }
446
447 struct acpi_gpe_block_status_context {
448 struct acpi_gpe_register_info *gpe_skip_register_info;
449 u8 gpe_skip_mask;
450 u8 retval;
451 };
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467 static acpi_status
468 acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
469 struct acpi_gpe_block_info *gpe_block,
470 void *context)
471 {
472 struct acpi_gpe_block_status_context *c = context;
473 struct acpi_gpe_register_info *gpe_register_info;
474 u64 in_enable, in_status;
475 acpi_status status;
476 u8 ret_mask;
477 u32 i;
478
479
480
481 for (i = 0; i < gpe_block->register_count; i++) {
482 gpe_register_info = &gpe_block->register_info[i];
483
484 status = acpi_hw_read(&in_enable,
485 &gpe_register_info->enable_address);
486 if (ACPI_FAILURE(status)) {
487 continue;
488 }
489
490 status = acpi_hw_read(&in_status,
491 &gpe_register_info->status_address);
492 if (ACPI_FAILURE(status)) {
493 continue;
494 }
495
496 ret_mask = in_enable & in_status;
497 if (ret_mask && c->gpe_skip_register_info == gpe_register_info) {
498 ret_mask &= ~c->gpe_skip_mask;
499 }
500 c->retval |= ret_mask;
501 }
502
503 return (AE_OK);
504 }
505
506
507
508
509
510
511
512
513
514
515
516
517
518 acpi_status acpi_hw_disable_all_gpes(void)
519 {
520 acpi_status status;
521
522 ACPI_FUNCTION_TRACE(hw_disable_all_gpes);
523
524 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
525 return_ACPI_STATUS(status);
526 }
527
528
529
530
531
532
533
534
535
536
537
538
539
540 acpi_status acpi_hw_enable_all_runtime_gpes(void)
541 {
542 acpi_status status;
543
544 ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes);
545
546 status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL);
547 return_ACPI_STATUS(status);
548 }
549
550
551
552
553
554
555
556
557
558
559
560
561
562 acpi_status acpi_hw_enable_all_wakeup_gpes(void)
563 {
564 acpi_status status;
565
566 ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes);
567
568 status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
569 return_ACPI_STATUS(status);
570 }
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587 u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number)
588 {
589 struct acpi_gpe_block_status_context context = {
590 .gpe_skip_register_info = NULL,
591 .retval = 0,
592 };
593 struct acpi_gpe_event_info *gpe_event_info;
594 acpi_cpu_flags flags;
595
596 ACPI_FUNCTION_TRACE(acpi_hw_check_all_gpes);
597
598 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
599
600 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_skip_device,
601 gpe_skip_number);
602 if (gpe_event_info) {
603 context.gpe_skip_register_info = gpe_event_info->register_info;
604 context.gpe_skip_mask = acpi_hw_get_gpe_register_bit(gpe_event_info);
605 }
606
607 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
608
609 (void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &context);
610 return (context.retval != 0);
611 }
612
613 #endif