diff options
Diffstat (limited to 'drivers/acpi/acpica/hwxface.c')
-rw-r--r-- | drivers/acpi/acpica/hwxface.c | 279 |
1 files changed, 107 insertions, 172 deletions
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index ae597c0ab53f..9829979f2bdd 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -107,19 +107,18 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | |||
107 | ACPI_FUNCTION_NAME(acpi_read); | 107 | ACPI_FUNCTION_NAME(acpi_read); |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * Must have a valid pointer to a GAS structure, and | 110 | * Must have a valid pointer to a GAS structure, and a non-zero address |
111 | * a non-zero address within. However, don't return an error | 111 | * within. |
112 | * because the PM1A/B code must not fail if B isn't present. | ||
113 | */ | 112 | */ |
114 | if (!reg) { | 113 | if (!reg) { |
115 | return (AE_OK); | 114 | return (AE_BAD_PARAMETER); |
116 | } | 115 | } |
117 | 116 | ||
118 | /* Get a local copy of the address. Handles possible alignment issues */ | 117 | /* Get a local copy of the address. Handles possible alignment issues */ |
119 | 118 | ||
120 | ACPI_MOVE_64_TO_64(&address, ®->address); | 119 | ACPI_MOVE_64_TO_64(&address, ®->address); |
121 | if (!address) { | 120 | if (!address) { |
122 | return (AE_OK); | 121 | return (AE_BAD_ADDRESS); |
123 | } | 122 | } |
124 | 123 | ||
125 | /* Supported widths are 8/16/32 */ | 124 | /* Supported widths are 8/16/32 */ |
@@ -134,8 +133,8 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | |||
134 | *value = 0; | 133 | *value = 0; |
135 | 134 | ||
136 | /* | 135 | /* |
137 | * Two address spaces supported: Memory or IO. | 136 | * Two address spaces supported: Memory or IO. PCI_Config is |
138 | * PCI_Config is not supported here because the GAS struct is insufficient | 137 | * not supported here because the GAS structure is insufficient |
139 | */ | 138 | */ |
140 | switch (reg->space_id) { | 139 | switch (reg->space_id) { |
141 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 140 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
@@ -147,7 +146,7 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | |||
147 | case ACPI_ADR_SPACE_SYSTEM_IO: | 146 | case ACPI_ADR_SPACE_SYSTEM_IO: |
148 | 147 | ||
149 | status = | 148 | status = |
150 | acpi_os_read_port((acpi_io_address) address, value, width); | 149 | acpi_hw_read_port((acpi_io_address) address, value, width); |
151 | break; | 150 | break; |
152 | 151 | ||
153 | default: | 152 | default: |
@@ -187,19 +186,18 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | |||
187 | ACPI_FUNCTION_NAME(acpi_write); | 186 | ACPI_FUNCTION_NAME(acpi_write); |
188 | 187 | ||
189 | /* | 188 | /* |
190 | * Must have a valid pointer to a GAS structure, and | 189 | * Must have a valid pointer to a GAS structure, and a non-zero address |
191 | * a non-zero address within. However, don't return an error | 190 | * within. |
192 | * because the PM1A/B code must not fail if B isn't present. | ||
193 | */ | 191 | */ |
194 | if (!reg) { | 192 | if (!reg) { |
195 | return (AE_OK); | 193 | return (AE_BAD_PARAMETER); |
196 | } | 194 | } |
197 | 195 | ||
198 | /* Get a local copy of the address. Handles possible alignment issues */ | 196 | /* Get a local copy of the address. Handles possible alignment issues */ |
199 | 197 | ||
200 | ACPI_MOVE_64_TO_64(&address, ®->address); | 198 | ACPI_MOVE_64_TO_64(&address, ®->address); |
201 | if (!address) { | 199 | if (!address) { |
202 | return (AE_OK); | 200 | return (AE_BAD_ADDRESS); |
203 | } | 201 | } |
204 | 202 | ||
205 | /* Supported widths are 8/16/32 */ | 203 | /* Supported widths are 8/16/32 */ |
@@ -222,7 +220,7 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | |||
222 | 220 | ||
223 | case ACPI_ADR_SPACE_SYSTEM_IO: | 221 | case ACPI_ADR_SPACE_SYSTEM_IO: |
224 | 222 | ||
225 | status = acpi_os_write_port((acpi_io_address) address, value, | 223 | status = acpi_hw_write_port((acpi_io_address) address, value, |
226 | width); | 224 | width); |
227 | break; | 225 | break; |
228 | 226 | ||
@@ -244,24 +242,36 @@ ACPI_EXPORT_SYMBOL(acpi_write) | |||
244 | 242 | ||
245 | /******************************************************************************* | 243 | /******************************************************************************* |
246 | * | 244 | * |
247 | * FUNCTION: acpi_get_register_unlocked | 245 | * FUNCTION: acpi_read_bit_register |
248 | * | 246 | * |
249 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 247 | * PARAMETERS: register_id - ID of ACPI Bit Register to access |
250 | * return_value - Value that was read from the register | 248 | * return_value - Value that was read from the register, |
249 | * normalized to bit position zero. | ||
251 | * | 250 | * |
252 | * RETURN: Status and the value read from specified Register. Value | 251 | * RETURN: Status and the value read from the specified Register. Value |
253 | * returned is normalized to bit0 (is shifted all the way right) | 252 | * returned is normalized to bit0 (is shifted all the way right) |
254 | * | 253 | * |
255 | * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock. | 254 | * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock. |
256 | * | 255 | * |
256 | * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and | ||
257 | * PM2 Control. | ||
258 | * | ||
259 | * Note: The hardware lock is not required when reading the ACPI bit registers | ||
260 | * since almost all of them are single bit and it does not matter that | ||
261 | * the parent hardware register can be split across two physical | ||
262 | * registers. The only multi-bit field is SLP_TYP in the PM1 control | ||
263 | * register, but this field does not cross an 8-bit boundary (nor does | ||
264 | * it make much sense to actually read this field.) | ||
265 | * | ||
257 | ******************************************************************************/ | 266 | ******************************************************************************/ |
258 | acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value) | 267 | acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value) |
259 | { | 268 | { |
260 | u32 register_value = 0; | ||
261 | struct acpi_bit_register_info *bit_reg_info; | 269 | struct acpi_bit_register_info *bit_reg_info; |
270 | u32 register_value; | ||
271 | u32 value; | ||
262 | acpi_status status; | 272 | acpi_status status; |
263 | 273 | ||
264 | ACPI_FUNCTION_TRACE(acpi_get_register_unlocked); | 274 | ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id); |
265 | 275 | ||
266 | /* Get the info structure corresponding to the requested ACPI Register */ | 276 | /* Get the info structure corresponding to the requested ACPI Register */ |
267 | 277 | ||
@@ -270,209 +280,133 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value) | |||
270 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 280 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
271 | } | 281 | } |
272 | 282 | ||
273 | /* Read from the register */ | 283 | /* Read the entire parent register */ |
274 | 284 | ||
275 | status = acpi_hw_register_read(bit_reg_info->parent_register, | 285 | status = acpi_hw_register_read(bit_reg_info->parent_register, |
276 | ®ister_value); | 286 | ®ister_value); |
277 | 287 | if (ACPI_FAILURE(status)) { | |
278 | if (ACPI_SUCCESS(status)) { | 288 | return_ACPI_STATUS(status); |
279 | |||
280 | /* Normalize the value that was read */ | ||
281 | |||
282 | register_value = | ||
283 | ((register_value & bit_reg_info->access_bit_mask) | ||
284 | >> bit_reg_info->bit_position); | ||
285 | |||
286 | *return_value = register_value; | ||
287 | |||
288 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n", | ||
289 | register_value, | ||
290 | bit_reg_info->parent_register)); | ||
291 | } | 289 | } |
292 | 290 | ||
293 | return_ACPI_STATUS(status); | 291 | /* Normalize the value that was read, mask off other bits */ |
294 | } | ||
295 | 292 | ||
296 | ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked) | 293 | value = ((register_value & bit_reg_info->access_bit_mask) |
294 | >> bit_reg_info->bit_position); | ||
297 | 295 | ||
298 | /******************************************************************************* | 296 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
299 | * | 297 | "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n", |
300 | * FUNCTION: acpi_get_register | 298 | register_id, bit_reg_info->parent_register, |
301 | * | 299 | register_value, value)); |
302 | * PARAMETERS: register_id - ID of ACPI bit_register to access | ||
303 | * return_value - Value that was read from the register | ||
304 | * | ||
305 | * RETURN: Status and the value read from specified Register. Value | ||
306 | * returned is normalized to bit0 (is shifted all the way right) | ||
307 | * | ||
308 | * DESCRIPTION: ACPI bit_register read function. | ||
309 | * | ||
310 | ******************************************************************************/ | ||
311 | acpi_status acpi_get_register(u32 register_id, u32 *return_value) | ||
312 | { | ||
313 | acpi_status status; | ||
314 | acpi_cpu_flags flags; | ||
315 | |||
316 | flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | ||
317 | status = acpi_get_register_unlocked(register_id, return_value); | ||
318 | acpi_os_release_lock(acpi_gbl_hardware_lock, flags); | ||
319 | 300 | ||
320 | return (status); | 301 | *return_value = value; |
302 | return_ACPI_STATUS(AE_OK); | ||
321 | } | 303 | } |
322 | 304 | ||
323 | ACPI_EXPORT_SYMBOL(acpi_get_register) | 305 | ACPI_EXPORT_SYMBOL(acpi_read_bit_register) |
324 | 306 | ||
325 | /******************************************************************************* | 307 | /******************************************************************************* |
326 | * | 308 | * |
327 | * FUNCTION: acpi_set_register | 309 | * FUNCTION: acpi_write_bit_register |
328 | * | 310 | * |
329 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 311 | * PARAMETERS: register_id - ID of ACPI Bit Register to access |
330 | * Value - (only used on write) value to write to the | 312 | * Value - Value to write to the register, in bit |
331 | * Register, NOT pre-normalized to the bit pos | 313 | * position zero. The bit is automaticallly |
314 | * shifted to the correct position. | ||
332 | * | 315 | * |
333 | * RETURN: Status | 316 | * RETURN: Status |
334 | * | 317 | * |
335 | * DESCRIPTION: ACPI Bit Register write function. | 318 | * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock |
319 | * since most operations require a read/modify/write sequence. | ||
320 | * | ||
321 | * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and | ||
322 | * PM2 Control. | ||
323 | * | ||
324 | * Note that at this level, the fact that there may be actually two | ||
325 | * hardware registers (A and B - and B may not exist) is abstracted. | ||
336 | * | 326 | * |
337 | ******************************************************************************/ | 327 | ******************************************************************************/ |
338 | acpi_status acpi_set_register(u32 register_id, u32 value) | 328 | acpi_status acpi_write_bit_register(u32 register_id, u32 value) |
339 | { | 329 | { |
340 | u32 register_value = 0; | ||
341 | struct acpi_bit_register_info *bit_reg_info; | 330 | struct acpi_bit_register_info *bit_reg_info; |
342 | acpi_status status; | ||
343 | acpi_cpu_flags lock_flags; | 331 | acpi_cpu_flags lock_flags; |
332 | u32 register_value; | ||
333 | acpi_status status = AE_OK; | ||
344 | 334 | ||
345 | ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id); | 335 | ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id); |
346 | 336 | ||
347 | /* Get the info structure corresponding to the requested ACPI Register */ | 337 | /* Get the info structure corresponding to the requested ACPI Register */ |
348 | 338 | ||
349 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); | 339 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); |
350 | if (!bit_reg_info) { | 340 | if (!bit_reg_info) { |
351 | ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X", | ||
352 | register_id)); | ||
353 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 341 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
354 | } | 342 | } |
355 | 343 | ||
356 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 344 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
357 | 345 | ||
358 | /* Always do a register read first so we can insert the new bits */ | ||
359 | |||
360 | status = acpi_hw_register_read(bit_reg_info->parent_register, | ||
361 | ®ister_value); | ||
362 | if (ACPI_FAILURE(status)) { | ||
363 | goto unlock_and_exit; | ||
364 | } | ||
365 | |||
366 | /* | 346 | /* |
367 | * Decode the Register ID | 347 | * At this point, we know that the parent register is one of the |
368 | * Register ID = [Register block ID] | [bit ID] | 348 | * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control |
369 | * | ||
370 | * Check bit ID to fine locate Register offset. | ||
371 | * Check Mask to determine Register offset, and then read-write. | ||
372 | */ | 349 | */ |
373 | switch (bit_reg_info->parent_register) { | 350 | if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) { |
374 | case ACPI_REGISTER_PM1_STATUS: | ||
375 | |||
376 | /* | 351 | /* |
377 | * Status Registers are different from the rest. Clear by | 352 | * 1) Case for PM1 Enable, PM1 Control, and PM2 Control |
378 | * writing 1, and writing 0 has no effect. So, the only relevant | 353 | * |
379 | * information is the single bit we're interested in, all others should | 354 | * Perform a register read to preserve the bits that we are not |
380 | * be written as 0 so they will be left unchanged. | 355 | * interested in |
381 | */ | 356 | */ |
382 | value = ACPI_REGISTER_PREPARE_BITS(value, | 357 | status = acpi_hw_register_read(bit_reg_info->parent_register, |
383 | bit_reg_info->bit_position, | ||
384 | bit_reg_info-> | ||
385 | access_bit_mask); | ||
386 | if (value) { | ||
387 | status = | ||
388 | acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, | ||
389 | (u16) value); | ||
390 | register_value = 0; | ||
391 | } | ||
392 | break; | ||
393 | |||
394 | case ACPI_REGISTER_PM1_ENABLE: | ||
395 | |||
396 | ACPI_REGISTER_INSERT_VALUE(register_value, | ||
397 | bit_reg_info->bit_position, | ||
398 | bit_reg_info->access_bit_mask, | ||
399 | value); | ||
400 | |||
401 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE, | ||
402 | (u16) register_value); | ||
403 | break; | ||
404 | |||
405 | case ACPI_REGISTER_PM1_CONTROL: | ||
406 | |||
407 | /* | ||
408 | * Write the PM1 Control register. | ||
409 | * Note that at this level, the fact that there are actually TWO | ||
410 | * registers (A and B - and B may not exist) is abstracted. | ||
411 | */ | ||
412 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n", | ||
413 | register_value)); | ||
414 | |||
415 | ACPI_REGISTER_INSERT_VALUE(register_value, | ||
416 | bit_reg_info->bit_position, | ||
417 | bit_reg_info->access_bit_mask, | ||
418 | value); | ||
419 | |||
420 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL, | ||
421 | (u16) register_value); | ||
422 | break; | ||
423 | |||
424 | case ACPI_REGISTER_PM2_CONTROL: | ||
425 | |||
426 | status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL, | ||
427 | ®ister_value); | 358 | ®ister_value); |
428 | if (ACPI_FAILURE(status)) { | 359 | if (ACPI_FAILURE(status)) { |
429 | goto unlock_and_exit; | 360 | goto unlock_and_exit; |
430 | } | 361 | } |
431 | 362 | ||
432 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 363 | /* |
433 | "PM2 control: Read %X from %8.8X%8.8X\n", | 364 | * Insert the input bit into the value that was just read |
434 | register_value, | 365 | * and write the register |
435 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. | 366 | */ |
436 | xpm2_control_block. | ||
437 | address))); | ||
438 | |||
439 | ACPI_REGISTER_INSERT_VALUE(register_value, | 367 | ACPI_REGISTER_INSERT_VALUE(register_value, |
440 | bit_reg_info->bit_position, | 368 | bit_reg_info->bit_position, |
441 | bit_reg_info->access_bit_mask, | 369 | bit_reg_info->access_bit_mask, |
442 | value); | 370 | value); |
443 | 371 | ||
444 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 372 | status = acpi_hw_register_write(bit_reg_info->parent_register, |
445 | "About to write %4.4X to %8.8X%8.8X\n", | 373 | register_value); |
446 | register_value, | 374 | } else { |
447 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. | 375 | /* |
448 | xpm2_control_block. | 376 | * 2) Case for PM1 Status |
449 | address))); | 377 | * |
378 | * The Status register is different from the rest. Clear an event | ||
379 | * by writing 1, writing 0 has no effect. So, the only relevant | ||
380 | * information is the single bit we're interested in, all others | ||
381 | * should be written as 0 so they will be left unchanged. | ||
382 | */ | ||
383 | register_value = ACPI_REGISTER_PREPARE_BITS(value, | ||
384 | bit_reg_info-> | ||
385 | bit_position, | ||
386 | bit_reg_info-> | ||
387 | access_bit_mask); | ||
450 | 388 | ||
451 | status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL, | 389 | /* No need to write the register if value is all zeros */ |
452 | (u8) (register_value)); | ||
453 | break; | ||
454 | 390 | ||
455 | default: | 391 | if (register_value) { |
456 | break; | 392 | status = |
393 | acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, | ||
394 | register_value); | ||
395 | } | ||
457 | } | 396 | } |
458 | 397 | ||
459 | unlock_and_exit: | 398 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
460 | 399 | "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n", | |
461 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 400 | register_id, bit_reg_info->parent_register, value, |
462 | 401 | register_value)); | |
463 | /* Normalize the value that was read */ | ||
464 | 402 | ||
465 | ACPI_DEBUG_EXEC(register_value = | 403 | unlock_and_exit: |
466 | ((register_value & bit_reg_info->access_bit_mask) >> | ||
467 | bit_reg_info->bit_position)); | ||
468 | 404 | ||
469 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 405 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); |
470 | "Set bits: %8.8X actual %8.8X register %X\n", value, | ||
471 | register_value, bit_reg_info->parent_register)); | ||
472 | return_ACPI_STATUS(status); | 406 | return_ACPI_STATUS(status); |
473 | } | 407 | } |
474 | 408 | ||
475 | ACPI_EXPORT_SYMBOL(acpi_set_register) | 409 | ACPI_EXPORT_SYMBOL(acpi_write_bit_register) |
476 | 410 | ||
477 | /******************************************************************************* | 411 | /******************************************************************************* |
478 | * | 412 | * |
@@ -534,7 +468,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) | |||
534 | 468 | ||
535 | /* It must be of type Package */ | 469 | /* It must be of type Package */ |
536 | 470 | ||
537 | else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { | 471 | else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) { |
538 | ACPI_ERROR((AE_INFO, | 472 | ACPI_ERROR((AE_INFO, |
539 | "Sleep State return object is not a Package")); | 473 | "Sleep State return object is not a Package")); |
540 | status = AE_AML_OPERAND_TYPE; | 474 | status = AE_AML_OPERAND_TYPE; |
@@ -555,12 +489,13 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) | |||
555 | 489 | ||
556 | /* The first two elements must both be of type Integer */ | 490 | /* The first two elements must both be of type Integer */ |
557 | 491 | ||
558 | else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) | 492 | else if (((info->return_object->package.elements[0])->common.type |
559 | != ACPI_TYPE_INTEGER) || | 493 | != ACPI_TYPE_INTEGER) || |
560 | (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) | 494 | ((info->return_object->package.elements[1])->common.type |
561 | != ACPI_TYPE_INTEGER)) { | 495 | != ACPI_TYPE_INTEGER)) { |
562 | ACPI_ERROR((AE_INFO, | 496 | ACPI_ERROR((AE_INFO, |
563 | "Sleep State return package elements are not both Integers (%s, %s)", | 497 | "Sleep State return package elements are not both Integers " |
498 | "(%s, %s)", | ||
564 | acpi_ut_get_object_type_name(info->return_object-> | 499 | acpi_ut_get_object_type_name(info->return_object-> |
565 | package.elements[0]), | 500 | package.elements[0]), |
566 | acpi_ut_get_object_type_name(info->return_object-> | 501 | acpi_ut_get_object_type_name(info->return_object-> |