1 2 /****************************************************************************** 3 * 4 * Module Name: hwgpe - Low level GPE enable/disable/clear functions 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2011, 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 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 * gpe_register_info - Info block for the GPE register 64 * 65 * RETURN: Register mask with a one in the GPE bit position 66 * 67 * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the 68 * correct position for the input GPE. 69 * 70 ******************************************************************************/ 71 72 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, 73 struct acpi_gpe_register_info *gpe_register_info) 74 { 75 return (u32)1 << (gpe_event_info->gpe_number - 76 gpe_register_info->base_gpe_number); 77 } 78 79 /****************************************************************************** 80 * 81 * FUNCTION: acpi_hw_low_set_gpe 82 * 83 * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled 84 * action - Enable or disable 85 * 86 * RETURN: Status 87 * 88 * DESCRIPTION: Enable or disable a single GPE in the parent enable register. 89 * 90 ******************************************************************************/ 91 92 acpi_status 93 acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) 94 { 95 struct acpi_gpe_register_info *gpe_register_info; 96 acpi_status status; 97 u32 enable_mask; 98 u32 register_bit; 99 100 ACPI_FUNCTION_ENTRY(); 101 102 /* Get the info block for the entire GPE register */ 103 104 gpe_register_info = gpe_event_info->register_info; 105 if (!gpe_register_info) { 106 return (AE_NOT_EXIST); 107 } 108 109 /* Get current value of the enable register that contains this GPE */ 110 111 status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address); 112 if (ACPI_FAILURE(status)) { 113 return (status); 114 } 115 116 /* Set or clear just the bit that corresponds to this GPE */ 117 118 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, 119 gpe_register_info); 120 switch (action) { 121 case ACPI_GPE_CONDITIONAL_ENABLE: 122 123 /* Only enable if the enable_for_run bit is set */ 124 125 if (!(register_bit & gpe_register_info->enable_for_run)) { 126 return (AE_BAD_PARAMETER); 127 } 128 129 /*lint -fallthrough */ 130 131 case ACPI_GPE_ENABLE: 132 ACPI_SET_BIT(enable_mask, register_bit); 133 break; 134 135 case ACPI_GPE_DISABLE: 136 ACPI_CLEAR_BIT(enable_mask, register_bit); 137 break; 138 139 default: 140 ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action)); 141 return (AE_BAD_PARAMETER); 142 } 143 144 /* Write the updated enable mask */ 145 146 status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); 147 return (status); 148 } 149 150 /****************************************************************************** 151 * 152 * FUNCTION: acpi_hw_clear_gpe 153 * 154 * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared 155 * 156 * RETURN: Status 157 * 158 * DESCRIPTION: Clear the status bit for a single GPE. 159 * 160 ******************************************************************************/ 161 162 acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) 163 { 164 struct acpi_gpe_register_info *gpe_register_info; 165 acpi_status status; 166 u32 register_bit; 167 168 ACPI_FUNCTION_ENTRY(); 169 170 /* Get the info block for the entire GPE register */ 171 172 gpe_register_info = gpe_event_info->register_info; 173 if (!gpe_register_info) { 174 return (AE_NOT_EXIST); 175 } 176 177 /* 178 * Write a one to the appropriate bit in the status register to 179 * clear this GPE. 180 */ 181 register_bit = 182 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); 183 184 status = acpi_hw_write(register_bit, 185 &gpe_register_info->status_address); 186 187 return (status); 188 } 189 190 /****************************************************************************** 191 * 192 * FUNCTION: acpi_hw_get_gpe_status 193 * 194 * PARAMETERS: gpe_event_info - Info block for the GPE to queried 195 * event_status - Where the GPE status is returned 196 * 197 * RETURN: Status 198 * 199 * DESCRIPTION: Return the status of a single GPE. 200 * 201 ******************************************************************************/ 202 203 acpi_status 204 acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, 205 acpi_event_status * event_status) 206 { 207 u32 in_byte; 208 u32 register_bit; 209 struct acpi_gpe_register_info *gpe_register_info; 210 acpi_event_status local_event_status = 0; 211 acpi_status status; 212 213 ACPI_FUNCTION_ENTRY(); 214 215 if (!event_status) { 216 return (AE_BAD_PARAMETER); 217 } 218 219 /* Get the info block for the entire GPE register */ 220 221 gpe_register_info = gpe_event_info->register_info; 222 223 /* Get the register bitmask for this GPE */ 224 225 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, 226 gpe_register_info); 227 228 /* GPE currently enabled? (enabled for runtime?) */ 229 230 if (register_bit & gpe_register_info->enable_for_run) { 231 local_event_status |= ACPI_EVENT_FLAG_ENABLED; 232 } 233 234 /* GPE enabled for wake? */ 235 236 if (register_bit & gpe_register_info->enable_for_wake) { 237 local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED; 238 } 239 240 /* GPE currently active (status bit == 1)? */ 241 242 status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); 243 if (ACPI_FAILURE(status)) { 244 return (status); 245 } 246 247 if (register_bit & in_byte) { 248 local_event_status |= ACPI_EVENT_FLAG_SET; 249 } 250 251 /* Set return value */ 252 253 (*event_status) = local_event_status; 254 return (AE_OK); 255 } 256 257 /****************************************************************************** 258 * 259 * FUNCTION: acpi_hw_disable_gpe_block 260 * 261 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 262 * gpe_block - Gpe Block info 263 * 264 * RETURN: Status 265 * 266 * DESCRIPTION: Disable all GPEs within a single GPE block 267 * 268 ******************************************************************************/ 269 270 acpi_status 271 acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 272 struct acpi_gpe_block_info *gpe_block, void *context) 273 { 274 u32 i; 275 acpi_status status; 276 277 /* Examine each GPE Register within the block */ 278 279 for (i = 0; i < gpe_block->register_count; i++) { 280 281 /* Disable all GPEs in this register */ 282 283 status = 284 acpi_hw_write(0x00, 285 &gpe_block->register_info[i].enable_address); 286 if (ACPI_FAILURE(status)) { 287 return (status); 288 } 289 } 290 291 return (AE_OK); 292 } 293 294 /****************************************************************************** 295 * 296 * FUNCTION: acpi_hw_clear_gpe_block 297 * 298 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 299 * gpe_block - Gpe Block info 300 * 301 * RETURN: Status 302 * 303 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block 304 * 305 ******************************************************************************/ 306 307 acpi_status 308 acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 309 struct acpi_gpe_block_info *gpe_block, void *context) 310 { 311 u32 i; 312 acpi_status status; 313 314 /* Examine each GPE Register within the block */ 315 316 for (i = 0; i < gpe_block->register_count; i++) { 317 318 /* Clear status on all GPEs in this register */ 319 320 status = 321 acpi_hw_write(0xFF, 322 &gpe_block->register_info[i].status_address); 323 if (ACPI_FAILURE(status)) { 324 return (status); 325 } 326 } 327 328 return (AE_OK); 329 } 330 331 /****************************************************************************** 332 * 333 * FUNCTION: acpi_hw_enable_runtime_gpe_block 334 * 335 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 336 * gpe_block - Gpe Block info 337 * 338 * RETURN: Status 339 * 340 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes 341 * combination wake/run GPEs. 342 * 343 ******************************************************************************/ 344 345 acpi_status 346 acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 347 struct acpi_gpe_block_info *gpe_block, void *context) 348 { 349 u32 i; 350 acpi_status status; 351 352 /* NOTE: assumes that all GPEs are currently disabled */ 353 354 /* Examine each GPE Register within the block */ 355 356 for (i = 0; i < gpe_block->register_count; i++) { 357 if (!gpe_block->register_info[i].enable_for_run) { 358 continue; 359 } 360 361 /* Enable all "runtime" GPEs in this register */ 362 363 status = 364 acpi_hw_write(gpe_block->register_info[i].enable_for_run, 365 &gpe_block->register_info[i].enable_address); 366 if (ACPI_FAILURE(status)) { 367 return (status); 368 } 369 } 370 371 return (AE_OK); 372 } 373 374 /****************************************************************************** 375 * 376 * FUNCTION: acpi_hw_enable_wakeup_gpe_block 377 * 378 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 379 * gpe_block - Gpe Block info 380 * 381 * RETURN: Status 382 * 383 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes 384 * combination wake/run GPEs. 385 * 386 ******************************************************************************/ 387 388 static acpi_status 389 acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 390 struct acpi_gpe_block_info *gpe_block, 391 void *context) 392 { 393 u32 i; 394 acpi_status status; 395 396 /* Examine each GPE Register within the block */ 397 398 for (i = 0; i < gpe_block->register_count; i++) { 399 if (!gpe_block->register_info[i].enable_for_wake) { 400 continue; 401 } 402 403 /* Enable all "wake" GPEs in this register */ 404 405 status = 406 acpi_hw_write(gpe_block->register_info[i].enable_for_wake, 407 &gpe_block->register_info[i].enable_address); 408 if (ACPI_FAILURE(status)) { 409 return (status); 410 } 411 } 412 413 return (AE_OK); 414 } 415 416 /****************************************************************************** 417 * 418 * FUNCTION: acpi_hw_disable_all_gpes 419 * 420 * PARAMETERS: None 421 * 422 * RETURN: Status 423 * 424 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 425 * 426 ******************************************************************************/ 427 428 acpi_status acpi_hw_disable_all_gpes(void) 429 { 430 acpi_status status; 431 432 ACPI_FUNCTION_TRACE(hw_disable_all_gpes); 433 434 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL); 435 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); 436 return_ACPI_STATUS(status); 437 } 438 439 /****************************************************************************** 440 * 441 * FUNCTION: acpi_hw_enable_all_runtime_gpes 442 * 443 * PARAMETERS: None 444 * 445 * RETURN: Status 446 * 447 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 448 * 449 ******************************************************************************/ 450 451 acpi_status acpi_hw_enable_all_runtime_gpes(void) 452 { 453 acpi_status status; 454 455 ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes); 456 457 status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL); 458 return_ACPI_STATUS(status); 459 } 460 461 /****************************************************************************** 462 * 463 * FUNCTION: acpi_hw_enable_all_wakeup_gpes 464 * 465 * PARAMETERS: None 466 * 467 * RETURN: Status 468 * 469 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks 470 * 471 ******************************************************************************/ 472 473 acpi_status acpi_hw_enable_all_wakeup_gpes(void) 474 { 475 acpi_status status; 476 477 ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes); 478 479 status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL); 480 return_ACPI_STATUS(status); 481 } 482