1 /******************************************************************************
2 *
3 * Module Name: evgpeblk - GPE block creation and initialization.
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acevents.h"
47 #include "acnamesp.h"
48
49 #define _COMPONENT ACPI_EVENTS
50 ACPI_MODULE_NAME ("evgpeblk")
51
52 /* Local prototypes */
53
54 static ACPI_STATUS
55 AcpiEvInstallGpeBlock (
56 ACPI_GPE_BLOCK_INFO *GpeBlock,
57 UINT32 InterruptNumber);
58
59 static ACPI_STATUS
60 AcpiEvCreateGpeInfoBlocks (
61 ACPI_GPE_BLOCK_INFO *GpeBlock);
62
63
64 /*******************************************************************************
65 *
66 * FUNCTION: AcpiEvInstallGpeBlock
67 *
68 * PARAMETERS: GpeBlock - New GPE block
69 * InterruptNumber - Xrupt to be associated with this
70 * GPE block
71 *
78 static ACPI_STATUS
79 AcpiEvInstallGpeBlock (
80 ACPI_GPE_BLOCK_INFO *GpeBlock,
81 UINT32 InterruptNumber)
82 {
83 ACPI_GPE_BLOCK_INFO *NextGpeBlock;
84 ACPI_GPE_XRUPT_INFO *GpeXruptBlock;
85 ACPI_STATUS Status;
86 ACPI_CPU_FLAGS Flags;
87
88
89 ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
90
91
92 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
93 if (ACPI_FAILURE (Status))
94 {
95 return_ACPI_STATUS (Status);
96 }
97
98 GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptNumber);
99 if (!GpeXruptBlock)
100 {
101 Status = AE_NO_MEMORY;
102 goto UnlockAndExit;
103 }
104
105 /* Install the new block at the end of the list with lock */
106
107 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
108 if (GpeXruptBlock->GpeBlockListHead)
109 {
110 NextGpeBlock = GpeXruptBlock->GpeBlockListHead;
111 while (NextGpeBlock->Next)
112 {
113 NextGpeBlock = NextGpeBlock->Next;
114 }
115
116 NextGpeBlock->Next = GpeBlock;
117 GpeBlock->Previous = NextGpeBlock;
118 }
119 else
120 {
121 GpeXruptBlock->GpeBlockListHead = GpeBlock;
122 }
123
124 GpeBlock->XruptBlock = GpeXruptBlock;
125 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
126
127
128 UnlockAndExit:
129 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
130 return_ACPI_STATUS (Status);
131 }
132
133
134 /*******************************************************************************
135 *
136 * FUNCTION: AcpiEvDeleteGpeBlock
137 *
138 * PARAMETERS: GpeBlock - Existing GPE block
139 *
140 * RETURN: Status
141 *
142 * DESCRIPTION: Remove a GPE block
143 *
144 ******************************************************************************/
145
146 ACPI_STATUS
147 AcpiEvDeleteGpeBlock (
148 ACPI_GPE_BLOCK_INFO *GpeBlock)
149 {
401
402 ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress,
403 sizeof (ACPI_GENERIC_ADDRESS));
404
405 /*
406 * Create the RegisterInfo and EventInfo sub-structures
407 * Note: disables and clears all GPEs in the block
408 */
409 Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
410 if (ACPI_FAILURE (Status))
411 {
412 ACPI_FREE (GpeBlock);
413 return_ACPI_STATUS (Status);
414 }
415
416 /* Install the new block in the global lists */
417
418 Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
419 if (ACPI_FAILURE (Status))
420 {
421 ACPI_FREE (GpeBlock);
422 return_ACPI_STATUS (Status);
423 }
424
425 AcpiGbl_AllGpesInitialized = FALSE;
426
427 /* Find all GPE methods (_Lxx or_Exx) for this block */
428
429 WalkInfo.GpeBlock = GpeBlock;
430 WalkInfo.GpeDevice = GpeDevice;
431 WalkInfo.ExecuteByOwnerId = FALSE;
432
433 Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
434 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
435 AcpiEvMatchGpeMethod, NULL, &WalkInfo, NULL);
436
437 /* Return the new block */
438
439 if (ReturnGpeBlock)
440 {
441 (*ReturnGpeBlock) = GpeBlock;
442 }
443
444 ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
445 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
446 (UINT32) GpeBlock->BlockBaseNumber,
447 (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
448 GpeDevice->Name.Ascii, GpeBlock->RegisterCount,
449 InterruptNumber));
450
451 /* Update global count of currently available GPEs */
452
453 AcpiCurrentGpeCount += GpeBlock->GpeCount;
454 return_ACPI_STATUS (AE_OK);
455 }
456
457
458 /*******************************************************************************
459 *
460 * FUNCTION: AcpiEvInitializeGpeBlock
461 *
462 * PARAMETERS: ACPI_GPE_CALLBACK
463 *
464 * RETURN: Status
465 *
520 (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
521 {
522 continue;
523 }
524
525 Status = AcpiEvAddGpeReference (GpeEventInfo);
526 if (ACPI_FAILURE (Status))
527 {
528 ACPI_EXCEPTION ((AE_INFO, Status,
529 "Could not enable GPE 0x%02X",
530 GpeIndex + GpeBlock->BlockBaseNumber));
531 continue;
532 }
533
534 GpeEnabledCount++;
535 }
536 }
537
538 if (GpeEnabledCount)
539 {
540 ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
541 "Enabled %u GPEs in this block\n", GpeEnabledCount));
542 }
543
544 GpeBlock->Initialized = TRUE;
545 return_ACPI_STATUS (AE_OK);
546 }
547
|
1 /******************************************************************************
2 *
3 * Module Name: evgpeblk - GPE block creation and initialization.
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acevents.h"
47 #include "acnamesp.h"
48
49 #define _COMPONENT ACPI_EVENTS
50 ACPI_MODULE_NAME ("evgpeblk")
51
52 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
53
54 /* Local prototypes */
55
56 static ACPI_STATUS
57 AcpiEvInstallGpeBlock (
58 ACPI_GPE_BLOCK_INFO *GpeBlock,
59 UINT32 InterruptNumber);
60
61 static ACPI_STATUS
62 AcpiEvCreateGpeInfoBlocks (
63 ACPI_GPE_BLOCK_INFO *GpeBlock);
64
65
66 /*******************************************************************************
67 *
68 * FUNCTION: AcpiEvInstallGpeBlock
69 *
70 * PARAMETERS: GpeBlock - New GPE block
71 * InterruptNumber - Xrupt to be associated with this
72 * GPE block
73 *
80 static ACPI_STATUS
81 AcpiEvInstallGpeBlock (
82 ACPI_GPE_BLOCK_INFO *GpeBlock,
83 UINT32 InterruptNumber)
84 {
85 ACPI_GPE_BLOCK_INFO *NextGpeBlock;
86 ACPI_GPE_XRUPT_INFO *GpeXruptBlock;
87 ACPI_STATUS Status;
88 ACPI_CPU_FLAGS Flags;
89
90
91 ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
92
93
94 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
95 if (ACPI_FAILURE (Status))
96 {
97 return_ACPI_STATUS (Status);
98 }
99
100 Status = AcpiEvGetGpeXruptBlock (InterruptNumber, &GpeXruptBlock);
101 if (ACPI_FAILURE (Status))
102 {
103 goto UnlockAndExit;
104 }
105
106 /* Install the new block at the end of the list with lock */
107
108 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
109 if (GpeXruptBlock->GpeBlockListHead)
110 {
111 NextGpeBlock = GpeXruptBlock->GpeBlockListHead;
112 while (NextGpeBlock->Next)
113 {
114 NextGpeBlock = NextGpeBlock->Next;
115 }
116
117 NextGpeBlock->Next = GpeBlock;
118 GpeBlock->Previous = NextGpeBlock;
119 }
120 else
121 {
122 GpeXruptBlock->GpeBlockListHead = GpeBlock;
123 }
124
125 GpeBlock->XruptBlock = GpeXruptBlock;
126 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
127
128
129 UnlockAndExit:
130 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
131 return_ACPI_STATUS (Status);
132 }
133
134
135 /*******************************************************************************
136 *
137 * FUNCTION: AcpiEvDeleteGpeBlock
138 *
139 * PARAMETERS: GpeBlock - Existing GPE block
140 *
141 * RETURN: Status
142 *
143 * DESCRIPTION: Remove a GPE block
144 *
145 ******************************************************************************/
146
147 ACPI_STATUS
148 AcpiEvDeleteGpeBlock (
149 ACPI_GPE_BLOCK_INFO *GpeBlock)
150 {
402
403 ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress,
404 sizeof (ACPI_GENERIC_ADDRESS));
405
406 /*
407 * Create the RegisterInfo and EventInfo sub-structures
408 * Note: disables and clears all GPEs in the block
409 */
410 Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
411 if (ACPI_FAILURE (Status))
412 {
413 ACPI_FREE (GpeBlock);
414 return_ACPI_STATUS (Status);
415 }
416
417 /* Install the new block in the global lists */
418
419 Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
420 if (ACPI_FAILURE (Status))
421 {
422 ACPI_FREE (GpeBlock->RegisterInfo);
423 ACPI_FREE (GpeBlock->EventInfo);
424 ACPI_FREE (GpeBlock);
425 return_ACPI_STATUS (Status);
426 }
427
428 AcpiGbl_AllGpesInitialized = FALSE;
429
430 /* Find all GPE methods (_Lxx or_Exx) for this block */
431
432 WalkInfo.GpeBlock = GpeBlock;
433 WalkInfo.GpeDevice = GpeDevice;
434 WalkInfo.ExecuteByOwnerId = FALSE;
435
436 Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
437 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
438 AcpiEvMatchGpeMethod, NULL, &WalkInfo, NULL);
439
440 /* Return the new block */
441
442 if (ReturnGpeBlock)
443 {
444 (*ReturnGpeBlock) = GpeBlock;
445 }
446
447 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
448 " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X\n",
449 (UINT32) GpeBlock->BlockBaseNumber,
450 (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
451 GpeDevice->Name.Ascii, GpeBlock->RegisterCount,
452 InterruptNumber));
453
454 /* Update global count of currently available GPEs */
455
456 AcpiCurrentGpeCount += GpeBlock->GpeCount;
457 return_ACPI_STATUS (AE_OK);
458 }
459
460
461 /*******************************************************************************
462 *
463 * FUNCTION: AcpiEvInitializeGpeBlock
464 *
465 * PARAMETERS: ACPI_GPE_CALLBACK
466 *
467 * RETURN: Status
468 *
523 (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
524 {
525 continue;
526 }
527
528 Status = AcpiEvAddGpeReference (GpeEventInfo);
529 if (ACPI_FAILURE (Status))
530 {
531 ACPI_EXCEPTION ((AE_INFO, Status,
532 "Could not enable GPE 0x%02X",
533 GpeIndex + GpeBlock->BlockBaseNumber));
534 continue;
535 }
536
537 GpeEnabledCount++;
538 }
539 }
540
541 if (GpeEnabledCount)
542 {
543 ACPI_INFO ((AE_INFO,
544 "Enabled %u GPEs in block %02X to %02X", GpeEnabledCount,
545 (UINT32) GpeBlock->BlockBaseNumber,
546 (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1))));
547 }
548
549 GpeBlock->Initialized = TRUE;
550 return_ACPI_STATUS (AE_OK);
551 }
552
553 #endif /* !ACPI_REDUCED_HARDWARE */
|