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.17-rc2 420 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 /* Disable all GPEs in this register */ 218 219 status = acpi_hw_low_level_write(8, 0x00, 220 &gpe_block->register_info[i]. 221 enable_address); 222 if (ACPI_FAILURE(status)) { 223 return (status); 224 } 225 } 226 227 return (AE_OK); 228} 229 230/****************************************************************************** 231 * 232 * FUNCTION: acpi_hw_clear_gpe_block 233 * 234 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 235 * gpe_block - Gpe Block info 236 * 237 * RETURN: Status 238 * 239 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block 240 * 241 ******************************************************************************/ 242 243acpi_status 244acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, 245 struct acpi_gpe_block_info * gpe_block) 246{ 247 u32 i; 248 acpi_status status; 249 250 /* Examine each GPE Register within the block */ 251 252 for (i = 0; i < gpe_block->register_count; i++) { 253 /* Clear status on all GPEs in this register */ 254 255 status = acpi_hw_low_level_write(8, 0xFF, 256 &gpe_block->register_info[i]. 257 status_address); 258 if (ACPI_FAILURE(status)) { 259 return (status); 260 } 261 } 262 263 return (AE_OK); 264} 265 266/****************************************************************************** 267 * 268 * FUNCTION: acpi_hw_enable_runtime_gpe_block 269 * 270 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 271 * gpe_block - Gpe Block info 272 * 273 * RETURN: Status 274 * 275 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes 276 * combination wake/run GPEs. 277 * 278 ******************************************************************************/ 279 280acpi_status 281acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, 282 struct acpi_gpe_block_info * gpe_block) 283{ 284 u32 i; 285 acpi_status status; 286 287 /* NOTE: assumes that all GPEs are currently disabled */ 288 289 /* Examine each GPE Register within the block */ 290 291 for (i = 0; i < gpe_block->register_count; i++) { 292 if (!gpe_block->register_info[i].enable_for_run) { 293 continue; 294 } 295 296 /* Enable all "runtime" GPEs in this register */ 297 298 status = 299 acpi_hw_low_level_write(8, 300 gpe_block->register_info[i]. 301 enable_for_run, 302 &gpe_block->register_info[i]. 303 enable_address); 304 if (ACPI_FAILURE(status)) { 305 return (status); 306 } 307 } 308 309 return (AE_OK); 310} 311 312/****************************************************************************** 313 * 314 * FUNCTION: acpi_hw_enable_wakeup_gpe_block 315 * 316 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info 317 * gpe_block - Gpe Block info 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes 322 * combination wake/run GPEs. 323 * 324 ******************************************************************************/ 325 326static acpi_status 327acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 328 struct acpi_gpe_block_info *gpe_block) 329{ 330 u32 i; 331 acpi_status status; 332 333 /* Examine each GPE Register within the block */ 334 335 for (i = 0; i < gpe_block->register_count; i++) { 336 if (!gpe_block->register_info[i].enable_for_wake) { 337 continue; 338 } 339 340 /* Enable all "wake" GPEs in this register */ 341 342 status = acpi_hw_low_level_write(8, 343 gpe_block->register_info[i]. 344 enable_for_wake, 345 &gpe_block->register_info[i]. 346 enable_address); 347 if (ACPI_FAILURE(status)) { 348 return (status); 349 } 350 } 351 352 return (AE_OK); 353} 354 355/****************************************************************************** 356 * 357 * FUNCTION: acpi_hw_disable_all_gpes 358 * 359 * PARAMETERS: None 360 * 361 * RETURN: Status 362 * 363 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 364 * 365 ******************************************************************************/ 366 367acpi_status acpi_hw_disable_all_gpes(void) 368{ 369 acpi_status status; 370 371 ACPI_FUNCTION_TRACE("hw_disable_all_gpes"); 372 373 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block); 374 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); 375 return_ACPI_STATUS(status); 376} 377 378/****************************************************************************** 379 * 380 * FUNCTION: acpi_hw_enable_all_runtime_gpes 381 * 382 * PARAMETERS: None 383 * 384 * RETURN: Status 385 * 386 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 387 * 388 ******************************************************************************/ 389 390acpi_status acpi_hw_enable_all_runtime_gpes(void) 391{ 392 acpi_status status; 393 394 ACPI_FUNCTION_TRACE("hw_enable_all_runtime_gpes"); 395 396 status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block); 397 return_ACPI_STATUS(status); 398} 399 400/****************************************************************************** 401 * 402 * FUNCTION: acpi_hw_enable_all_wakeup_gpes 403 * 404 * PARAMETERS: None 405 * 406 * RETURN: Status 407 * 408 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks 409 * 410 ******************************************************************************/ 411 412acpi_status acpi_hw_enable_all_wakeup_gpes(void) 413{ 414 acpi_status status; 415 416 ACPI_FUNCTION_TRACE("hw_enable_all_wakeup_gpes"); 417 418 status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block); 419 return_ACPI_STATUS(status); 420}