Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
acpi
acpica
hwgpe.c
Go to the documentation of this file.
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 */
Generated on Thu Jan 10 2013 13:23:31 for Linux Kernel by
1.8.2