Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.19 422 lines 12 kB view raw
1 2/****************************************************************************** 3 * 4 * Module Name: hwgpe - Low level GPE enable/disable/clear functions 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2006, R. Byron Moore 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 <acpi/acevents.h> 47 48#define _COMPONENT ACPI_HARDWARE 49ACPI_MODULE_NAME("hwgpe") 50 51/* Local prototypes */ 52static acpi_status 53acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 54 struct acpi_gpe_block_info *gpe_block); 55 56/****************************************************************************** 57 * 58 * FUNCTION: acpi_hw_write_gpe_enable_reg 59 * 60 * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled 61 * 62 * RETURN: Status 63 * 64 * DESCRIPTION: Write a GPE enable register. Note: The bit for this GPE must 65 * already be cleared or set in the parent register 66 * enable_for_run mask. 67 * 68 ******************************************************************************/ 69 70acpi_status 71acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info) 72{ 73 struct acpi_gpe_register_info *gpe_register_info; 74 acpi_status status; 75 76 ACPI_FUNCTION_ENTRY(); 77 78 /* Get the info block for the entire GPE register */ 79 80 gpe_register_info = gpe_event_info->register_info; 81 if (!gpe_register_info) { 82 return (AE_NOT_EXIST); 83 } 84 85 /* Write the entire GPE (runtime) enable register */ 86 87 status = acpi_hw_low_level_write(8, gpe_register_info->enable_for_run, 88 &gpe_register_info->enable_address); 89 90 return (status); 91} 92 93/****************************************************************************** 94 * 95 * FUNCTION: acpi_hw_clear_gpe 96 * 97 * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared 98 * 99 * RETURN: Status 100 * 101 * DESCRIPTION: Clear the status bit for a single GPE. 102 * 103 ******************************************************************************/ 104 105acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) 106{ 107 acpi_status status; 108 109 ACPI_FUNCTION_ENTRY(); 110 111 /* 112 * Write a one to the appropriate bit in the status register to 113 * clear this GPE. 114 */ 115 status = acpi_hw_low_level_write(8, gpe_event_info->register_bit, 116 &gpe_event_info->register_info-> 117 status_address); 118 119 return (status); 120} 121 122/****************************************************************************** 123 * 124 * FUNCTION: acpi_hw_get_gpe_status 125 * 126 * PARAMETERS: gpe_event_info - Info block for the GPE to queried 127 * event_status - Where the GPE status is returned 128 * 129 * RETURN: Status 130 * 131 * DESCRIPTION: Return the status of a single GPE. 132 * 133 ******************************************************************************/ 134 135#ifdef ACPI_FUTURE_USAGE 136acpi_status 137acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, 138 acpi_event_status * event_status) 139{ 140 u32 in_byte; 141 u8 register_bit; 142 struct acpi_gpe_register_info *gpe_register_info; 143 acpi_status status; 144 acpi_event_status local_event_status = 0; 145 146 ACPI_FUNCTION_ENTRY(); 147 148 if (!event_status) { 149 return (AE_BAD_PARAMETER); 150 } 151 152 /* Get the info block for the entire GPE register */ 153 154 gpe_register_info = gpe_event_info->register_info; 155 156 /* Get the register bitmask for this GPE */ 157 158 register_bit = gpe_event_info->register_bit; 159 160 /* GPE currently enabled? (enabled for runtime?) */ 161 162 if (register_bit & gpe_register_info->enable_for_run) { 163 local_event_status |= ACPI_EVENT_FLAG_ENABLED; 164 } 165 166 /* GPE enabled for wake? */ 167 168 if (register_bit & gpe_register_info->enable_for_wake) { 169 local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED; 170 } 171 172 /* GPE currently active (status bit == 1)? */ 173 174 status = 175 acpi_hw_low_level_read(8, &in_byte, 176 &gpe_register_info->status_address); 177 if (ACPI_FAILURE(status)) { 178 goto unlock_and_exit; 179 } 180 181 if (register_bit & in_byte) { 182 local_event_status |= ACPI_EVENT_FLAG_SET; 183 } 184 185 /* Set return value */ 186 187 (*event_status) = local_event_status; 188 189 unlock_and_exit: 190 return (status); 191} 192#endif /* ACPI_FUTURE_USAGE */ 193 194/****************************************************************************** 195 * 196 * FUNCTION: acpi_hw_disable_gpe_block 197 * 198 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 199 * gpe_block - Gpe Block info 200 * 201 * RETURN: Status 202 * 203 * DESCRIPTION: Disable all GPEs within a single GPE block 204 * 205 ******************************************************************************/ 206 207acpi_status 208acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, 209 struct acpi_gpe_block_info * gpe_block) 210{ 211 u32 i; 212 acpi_status status; 213 214 /* Examine each GPE Register within the block */ 215 216 for (i = 0; i < gpe_block->register_count; i++) { 217 218 /* Disable all GPEs in this register */ 219 220 status = acpi_hw_low_level_write(8, 0x00, 221 &gpe_block->register_info[i]. 222 enable_address); 223 if (ACPI_FAILURE(status)) { 224 return (status); 225 } 226 } 227 228 return (AE_OK); 229} 230 231/****************************************************************************** 232 * 233 * FUNCTION: acpi_hw_clear_gpe_block 234 * 235 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 236 * gpe_block - Gpe Block info 237 * 238 * RETURN: Status 239 * 240 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block 241 * 242 ******************************************************************************/ 243 244acpi_status 245acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, 246 struct acpi_gpe_block_info * gpe_block) 247{ 248 u32 i; 249 acpi_status status; 250 251 /* Examine each GPE Register within the block */ 252 253 for (i = 0; i < gpe_block->register_count; i++) { 254 255 /* Clear status on all GPEs in this register */ 256 257 status = acpi_hw_low_level_write(8, 0xFF, 258 &gpe_block->register_info[i]. 259 status_address); 260 if (ACPI_FAILURE(status)) { 261 return (status); 262 } 263 } 264 265 return (AE_OK); 266} 267 268/****************************************************************************** 269 * 270 * FUNCTION: acpi_hw_enable_runtime_gpe_block 271 * 272 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 273 * gpe_block - Gpe Block info 274 * 275 * RETURN: Status 276 * 277 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes 278 * combination wake/run GPEs. 279 * 280 ******************************************************************************/ 281 282acpi_status 283acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, 284 struct acpi_gpe_block_info * gpe_block) 285{ 286 u32 i; 287 acpi_status status; 288 289 /* NOTE: assumes that all GPEs are currently disabled */ 290 291 /* Examine each GPE Register within the block */ 292 293 for (i = 0; i < gpe_block->register_count; i++) { 294 if (!gpe_block->register_info[i].enable_for_run) { 295 continue; 296 } 297 298 /* Enable all "runtime" GPEs in this register */ 299 300 status = 301 acpi_hw_low_level_write(8, 302 gpe_block->register_info[i]. 303 enable_for_run, 304 &gpe_block->register_info[i]. 305 enable_address); 306 if (ACPI_FAILURE(status)) { 307 return (status); 308 } 309 } 310 311 return (AE_OK); 312} 313 314/****************************************************************************** 315 * 316 * FUNCTION: acpi_hw_enable_wakeup_gpe_block 317 * 318 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 319 * gpe_block - Gpe Block info 320 * 321 * RETURN: Status 322 * 323 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes 324 * combination wake/run GPEs. 325 * 326 ******************************************************************************/ 327 328static acpi_status 329acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 330 struct acpi_gpe_block_info *gpe_block) 331{ 332 u32 i; 333 acpi_status status; 334 335 /* Examine each GPE Register within the block */ 336 337 for (i = 0; i < gpe_block->register_count; i++) { 338 if (!gpe_block->register_info[i].enable_for_wake) { 339 continue; 340 } 341 342 /* Enable all "wake" GPEs in this register */ 343 344 status = acpi_hw_low_level_write(8, 345 gpe_block->register_info[i]. 346 enable_for_wake, 347 &gpe_block->register_info[i]. 348 enable_address); 349 if (ACPI_FAILURE(status)) { 350 return (status); 351 } 352 } 353 354 return (AE_OK); 355} 356 357/****************************************************************************** 358 * 359 * FUNCTION: acpi_hw_disable_all_gpes 360 * 361 * PARAMETERS: None 362 * 363 * RETURN: Status 364 * 365 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 366 * 367 ******************************************************************************/ 368 369acpi_status acpi_hw_disable_all_gpes(void) 370{ 371 acpi_status status; 372 373 ACPI_FUNCTION_TRACE(hw_disable_all_gpes); 374 375 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block); 376 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); 377 return_ACPI_STATUS(status); 378} 379 380/****************************************************************************** 381 * 382 * FUNCTION: acpi_hw_enable_all_runtime_gpes 383 * 384 * PARAMETERS: None 385 * 386 * RETURN: Status 387 * 388 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 389 * 390 ******************************************************************************/ 391 392acpi_status acpi_hw_enable_all_runtime_gpes(void) 393{ 394 acpi_status status; 395 396 ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes); 397 398 status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block); 399 return_ACPI_STATUS(status); 400} 401 402/****************************************************************************** 403 * 404 * FUNCTION: acpi_hw_enable_all_wakeup_gpes 405 * 406 * PARAMETERS: None 407 * 408 * RETURN: Status 409 * 410 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks 411 * 412 ******************************************************************************/ 413 414acpi_status acpi_hw_enable_all_wakeup_gpes(void) 415{ 416 acpi_status status; 417 418 ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes); 419 420 status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block); 421 return_ACPI_STATUS(status); 422}