1/****************************************************************************** 2 * 3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable 4 * $Revision: 1.1.1.1 $ 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000, 2001 R. Byron Moore 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26 27#include "acpi.h" 28#include "achware.h" 29#include "acnamesp.h" 30#include "acevents.h" 31#include "amlcode.h" 32#include "acinterp.h" 33 34#define _COMPONENT ACPI_EVENTS 35 MODULE_NAME ("evxfevnt") 36 37 38/******************************************************************************* 39 * 40 * FUNCTION: Acpi_enable 41 * 42 * PARAMETERS: None 43 * 44 * RETURN: Status 45 * 46 * DESCRIPTION: Transfers the system into ACPI mode. 47 * 48 ******************************************************************************/ 49 50acpi_status 51acpi_enable (void) 52{ 53 acpi_status status; 54 55 56 FUNCTION_TRACE ("Acpi_enable"); 57 58 59 /* Make sure we've got ACPI tables */ 60 61 if (!acpi_gbl_DSDT) { 62 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!\n")); 63 return_ACPI_STATUS (AE_NO_ACPI_TABLES); 64 } 65 66 /* Make sure the BIOS supports ACPI mode */ 67 68 if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) { 69 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Only legacy mode supported!\n")); 70 return_ACPI_STATUS (AE_ERROR); 71 } 72 73 /* Transition to ACPI mode */ 74 75 status = acpi_hw_set_mode (SYS_MODE_ACPI); 76 if (ACPI_FAILURE (status)) { 77 ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Could not transition to ACPI mode.\n")); 78 return_ACPI_STATUS (status); 79 } 80 81 ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Transition to ACPI mode successful\n")); 82 83 return_ACPI_STATUS (status); 84} 85 86 87/******************************************************************************* 88 * 89 * FUNCTION: Acpi_disable 90 * 91 * PARAMETERS: None 92 * 93 * RETURN: Status 94 * 95 * DESCRIPTION: Returns the system to original ACPI/legacy mode, and 96 * uninstalls the SCI interrupt handler. 97 * 98 ******************************************************************************/ 99 100acpi_status 101acpi_disable (void) 102{ 103 acpi_status status; 104 105 106 FUNCTION_TRACE ("Acpi_disable"); 107 108 109 /* Restore original mode */ 110 111 status = acpi_hw_set_mode (acpi_gbl_original_mode); 112 if (ACPI_FAILURE (status)) { 113 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to transition to original mode")); 114 return_ACPI_STATUS (status); 115 } 116 117 /* Unload the SCI interrupt handler */ 118 119 acpi_ev_remove_sci_handler (); 120 acpi_ev_restore_acpi_state (); 121 122 return_ACPI_STATUS (status); 123} 124 125 126/******************************************************************************* 127 * 128 * FUNCTION: Acpi_enable_event 129 * 130 * PARAMETERS: Event - The fixed event or GPE to be enabled 131 * Type - The type of event 132 * Flags - Just enable, or also wake enable? 133 * 134 * RETURN: Status 135 * 136 * DESCRIPTION: Enable an ACPI event (fixed and general purpose) 137 * 138 ******************************************************************************/ 139 140acpi_status 141acpi_enable_event ( 142 u32 event, 143 u32 type, 144 u32 flags) 145{ 146 acpi_status status = AE_OK; 147 u32 register_id; 148 149 150 FUNCTION_TRACE ("Acpi_enable_event"); 151 152 153 /* The Type must be either Fixed Acpi_event or GPE */ 154 155 switch (type) { 156 157 case ACPI_EVENT_FIXED: 158 159 /* Decode the Fixed Acpi_event */ 160 161 switch (event) { 162 case ACPI_EVENT_PMTIMER: 163 register_id = TMR_EN; 164 break; 165 166 case ACPI_EVENT_GLOBAL: 167 register_id = GBL_EN; 168 break; 169 170 case ACPI_EVENT_POWER_BUTTON: 171 register_id = PWRBTN_EN; 172 break; 173 174 case ACPI_EVENT_SLEEP_BUTTON: 175 register_id = SLPBTN_EN; 176 break; 177 178 case ACPI_EVENT_RTC: 179 register_id = RTC_EN; 180 break; 181 182 default: 183 return_ACPI_STATUS (AE_BAD_PARAMETER); 184 break; 185 } 186 187 /* 188 * Enable the requested fixed event (by writing a one to the 189 * enable register bit) 190 */ 191 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); 192 193 if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { 194 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 195 "Fixed event bit clear when it should be set\n")); 196 return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); 197 } 198 199 break; 200 201 202 case ACPI_EVENT_GPE: 203 204 /* Ensure that we have a valid GPE number */ 205 206 if ((event > ACPI_GPE_MAX) || 207 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { 208 return_ACPI_STATUS (AE_BAD_PARAMETER); 209 } 210 211 212 /* Enable the requested GPE number */ 213 214 if (flags & ACPI_EVENT_ENABLE) { 215 acpi_hw_enable_gpe (event); 216 } 217 if (flags & ACPI_EVENT_WAKE_ENABLE) { 218 acpi_hw_enable_gpe_for_wakeup (event); 219 } 220 221 break; 222 223 224 default: 225 226 status = AE_BAD_PARAMETER; 227 } 228 229 230 return_ACPI_STATUS (status); 231} 232 233 234/******************************************************************************* 235 * 236 * FUNCTION: Acpi_disable_event 237 * 238 * PARAMETERS: Event - The fixed event or GPE to be enabled 239 * Type - The type of event, fixed or general purpose 240 * Flags - Wake disable vs. non-wake disable 241 * 242 * RETURN: Status 243 * 244 * DESCRIPTION: Disable an ACPI event (fixed and general purpose) 245 * 246 ******************************************************************************/ 247 248acpi_status 249acpi_disable_event ( 250 u32 event, 251 u32 type, 252 u32 flags) 253{ 254 acpi_status status = AE_OK; 255 u32 register_id; 256 257 258 FUNCTION_TRACE ("Acpi_disable_event"); 259 260 261 /* The Type must be either Fixed Acpi_event or GPE */ 262 263 switch (type) { 264 265 case ACPI_EVENT_FIXED: 266 267 /* Decode the Fixed Acpi_event */ 268 269 switch (event) { 270 case ACPI_EVENT_PMTIMER: 271 register_id = TMR_EN; 272 break; 273 274 case ACPI_EVENT_GLOBAL: 275 register_id = GBL_EN; 276 break; 277 278 case ACPI_EVENT_POWER_BUTTON: 279 register_id = PWRBTN_EN; 280 break; 281 282 case ACPI_EVENT_SLEEP_BUTTON: 283 register_id = SLPBTN_EN; 284 break; 285 286 case ACPI_EVENT_RTC: 287 register_id = RTC_EN; 288 break; 289 290 default: 291 return_ACPI_STATUS (AE_BAD_PARAMETER); 292 break; 293 } 294 295 /* 296 * Disable the requested fixed event (by writing a zero to the 297 * enable register bit) 298 */ 299 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0); 300 301 if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { 302 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 303 "Fixed event bit set when it should be clear,\n")); 304 return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); 305 } 306 307 break; 308 309 310 case ACPI_EVENT_GPE: 311 312 /* Ensure that we have a valid GPE number */ 313 314 if ((event > ACPI_GPE_MAX) || 315 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { 316 return_ACPI_STATUS (AE_BAD_PARAMETER); 317 } 318 319 /* Disable the requested GPE number */ 320 321 if (flags & ACPI_EVENT_DISABLE) { 322 acpi_hw_disable_gpe (event); 323 } 324 if (flags & ACPI_EVENT_WAKE_DISABLE) { 325 acpi_hw_disable_gpe_for_wakeup (event); 326 } 327 328 break; 329 330 331 default: 332 status = AE_BAD_PARAMETER; 333 } 334 335 return_ACPI_STATUS (status); 336} 337 338 339/******************************************************************************* 340 * 341 * FUNCTION: Acpi_clear_event 342 * 343 * PARAMETERS: Event - The fixed event or GPE to be cleared 344 * Type - The type of event 345 * 346 * RETURN: Status 347 * 348 * DESCRIPTION: Clear an ACPI event (fixed and general purpose) 349 * 350 ******************************************************************************/ 351 352acpi_status 353acpi_clear_event ( 354 u32 event, 355 u32 type) 356{ 357 acpi_status status = AE_OK; 358 u32 register_id; 359 360 361 FUNCTION_TRACE ("Acpi_clear_event"); 362 363 364 /* The Type must be either Fixed Acpi_event or GPE */ 365 366 switch (type) { 367 368 case ACPI_EVENT_FIXED: 369 370 /* Decode the Fixed Acpi_event */ 371 372 switch (event) { 373 case ACPI_EVENT_PMTIMER: 374 register_id = TMR_STS; 375 break; 376 377 case ACPI_EVENT_GLOBAL: 378 register_id = GBL_STS; 379 break; 380 381 case ACPI_EVENT_POWER_BUTTON: 382 register_id = PWRBTN_STS; 383 break; 384 385 case ACPI_EVENT_SLEEP_BUTTON: 386 register_id = SLPBTN_STS; 387 break; 388 389 case ACPI_EVENT_RTC: 390 register_id = RTC_STS; 391 break; 392 393 default: 394 return_ACPI_STATUS (AE_BAD_PARAMETER); 395 break; 396 } 397 398 /* 399 * Clear the requested fixed event (By writing a one to the 400 * status register bit) 401 */ 402 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); 403 break; 404 405 406 case ACPI_EVENT_GPE: 407 408 /* Ensure that we have a valid GPE number */ 409 410 if ((event > ACPI_GPE_MAX) || 411 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { 412 return_ACPI_STATUS (AE_BAD_PARAMETER); 413 } 414 415 416 acpi_hw_clear_gpe (event); 417 break; 418 419 420 default: 421 422 status = AE_BAD_PARAMETER; 423 } 424 425 return_ACPI_STATUS (status); 426} 427 428 429/******************************************************************************* 430 * 431 * FUNCTION: Acpi_get_event_status 432 * 433 * PARAMETERS: Event - The fixed event or GPE 434 * Type - The type of event 435 * Status - Where the current status of the event will 436 * be returned 437 * 438 * RETURN: Status 439 * 440 * DESCRIPTION: Obtains and returns the current status of the event 441 * 442 ******************************************************************************/ 443 444 445acpi_status 446acpi_get_event_status ( 447 u32 event, 448 u32 type, 449 acpi_event_status *event_status) 450{ 451 acpi_status status = AE_OK; 452 u32 register_id; 453 454 455 FUNCTION_TRACE ("Acpi_get_event_status"); 456 457 458 if (!event_status) { 459 return_ACPI_STATUS (AE_BAD_PARAMETER); 460 } 461 462 463 /* The Type must be either Fixed Acpi_event or GPE */ 464 465 switch (type) { 466 467 case ACPI_EVENT_FIXED: 468 469 /* Decode the Fixed Acpi_event */ 470 471 switch (event) { 472 case ACPI_EVENT_PMTIMER: 473 register_id = TMR_STS; 474 break; 475 476 case ACPI_EVENT_GLOBAL: 477 register_id = GBL_STS; 478 break; 479 480 case ACPI_EVENT_POWER_BUTTON: 481 register_id = PWRBTN_STS; 482 break; 483 484 case ACPI_EVENT_SLEEP_BUTTON: 485 register_id = SLPBTN_STS; 486 break; 487 488 case ACPI_EVENT_RTC: 489 register_id = RTC_STS; 490 break; 491 492 default: 493 return_ACPI_STATUS (AE_BAD_PARAMETER); 494 break; 495 } 496 497 /* Get the status of the requested fixed event */ 498 499 *event_status = acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, register_id); 500 break; 501 502 503 case ACPI_EVENT_GPE: 504 505 /* Ensure that we have a valid GPE number */ 506 507 if ((event > ACPI_GPE_MAX) || 508 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) { 509 return_ACPI_STATUS (AE_BAD_PARAMETER); 510 } 511 512 513 /* Obtain status on the requested GPE number */ 514 515 acpi_hw_get_gpe_status (event, event_status); 516 break; 517 518 519 default: 520 status = AE_BAD_PARAMETER; 521 } 522 523 return_ACPI_STATUS (status); 524} 525 526