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
15ACPI_MODULE_NAME("hwgpe")
16#if (!ACPI_REDUCED_HARDWARE)
17
18static acpi_status
19acpi_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
23static acpi_status
24acpi_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
40u32 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
63acpi_status
64acpi_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
140acpi_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
179acpi_status
180acpi_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
269static acpi_status
270acpi_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
294acpi_status
295acpi_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
331acpi_status
332acpi_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
369acpi_status
370acpi_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
417static acpi_status
418acpi_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
448
449
450
451
452
453
454
455
456
457
458
459acpi_status acpi_hw_disable_all_gpes(void)
460{
461 acpi_status status;
462
463 ACPI_FUNCTION_TRACE(hw_disable_all_gpes);
464
465 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
466 return_ACPI_STATUS(status);
467}
468
469
470
471
472
473
474
475
476
477
478
479
480
481acpi_status acpi_hw_enable_all_runtime_gpes(void)
482{
483 acpi_status status;
484
485 ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes);
486
487 status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL);
488 return_ACPI_STATUS(status);
489}
490
491
492
493
494
495
496
497
498
499
500
501
502
503acpi_status acpi_hw_enable_all_wakeup_gpes(void)
504{
505 acpi_status status;
506
507 ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes);
508
509 status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
510 return_ACPI_STATUS(status);
511}
512
513#endif
514