1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 1999-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 #define __NO_VERSION__ 25 26 #include "os-interface.h" 27 #include "nv-linux.h" 28 #include "nv-reg.h" 29 30 #include <linux/acpi.h> 31 32 #if defined(NV_LINUX_ACPI_EVENTS_SUPPORTED) 33 static NV_STATUS nv_acpi_extract_integer (const union acpi_object *, void *, NvU32, NvU32 *); 34 static NV_STATUS nv_acpi_extract_buffer (const union acpi_object *, void *, NvU32, NvU32 *); 35 static NV_STATUS nv_acpi_extract_package (const union acpi_object *, void *, NvU32, NvU32 *); 36 static NV_STATUS nv_acpi_extract_object (const union acpi_object *, void *, NvU32, NvU32 *); 37 38 static void nv_acpi_powersource_hotplug_event(acpi_handle, u32, void *); 39 static void nv_acpi_nvpcf_event (acpi_handle, u32, void *); 40 static acpi_status nv_acpi_find_methods (acpi_handle, u32, void *, void **); 41 static NV_STATUS nv_acpi_nvif_method (NvU32, NvU32, void *, NvU16, NvU32 *, void *, NvU16 *); 42 43 static NV_STATUS nv_acpi_wmmx_method (NvU32, NvU8 *, NvU16 *); 44 45 static acpi_handle nvif_handle = NULL; 46 static acpi_handle wmmx_handle = NULL; 47 48 // Used for AC Power Source Hotplug Handling 49 static acpi_handle psr_handle = NULL; 50 static acpi_handle psr_device_handle = NULL; 51 static nv_acpi_t *psr_nv_acpi_object = NULL; 52 53 static NvBool battery_present = NV_FALSE; 54 55 #define BIX_BATTERY_TECHNOLOGY_OFFSET 0x4 56 #define BIF_BATTERY_TECHNOLOGY_OFFSET 0x3 57 #define BATTERY_RECHARGABLE 0x1 58 59 /* Moved into acpi/video.h in Linux 4.10 */ 60 #ifndef ACPI_VIDEO_NOTIFY_PROBE 61 #define ACPI_VIDEO_NOTIFY_PROBE 0x81 62 #endif 63 64 /* Added to acpi/video.h in Linux 3.1 */ 65 #ifndef ACPI_VIDEO_CLASS 66 #define ACPI_VIDEO_CLASS "video" 67 #endif 68 69 // Used for NVPCF event handling 70 static acpi_handle nvpcf_handle = NULL; 71 static acpi_handle nvpcf_device_handle = NULL; 72 static nv_acpi_t *nvpcf_nv_acpi_object = NULL; 73 74 #define ACPI_NVPCF_EVENT_CHANGE 0xC0 75 76 static int nv_acpi_get_device_handle(nv_state_t *nv, acpi_handle *dev_handle) 77 { 78 nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv); 79 80 #if defined(DEVICE_ACPI_HANDLE) 81 *dev_handle = DEVICE_ACPI_HANDLE(nvl->dev); 82 return NV_TRUE; 83 #elif defined (ACPI_HANDLE) 84 *dev_handle = ACPI_HANDLE(nvl->dev); 85 return NV_TRUE; 86 #else 87 return NV_FALSE; 88 #endif 89 } 90 91 /* 92 * This callback will be invoked by the acpi_notifier_call_chain() 93 */ 94 static int nv_acpi_notifier_call_chain_handler( 95 struct notifier_block *nb, 96 unsigned long val, 97 void *data 98 ) 99 { 100 struct acpi_bus_event *info = data; 101 nv_stack_t *sp = NULL; 102 nv_linux_state_t *nvl = container_of(nb, nv_linux_state_t, acpi_nb); 103 nv_state_t *nv = NV_STATE_PTR(nvl); 104 105 /* 106 * The ACPI_VIDEO_NOTIFY_PROBE will be sent for display hot-plug/unplug. 107 * This event will be received first by the acpi-video driver 108 * and then it will be notified through acpi_notifier_call_chain(). 109 */ 110 if (!strcmp(info->device_class, ACPI_VIDEO_CLASS) && 111 (info->type == ACPI_VIDEO_NOTIFY_PROBE)) 112 { 113 /* 114 * Intentionally return NOTIFY_BAD to inform acpi-video to stop 115 * generating keypresses for this event. The default behavior in the 116 * acpi-video driver for an ACPI_VIDEO_NOTIFY_PROBE, is to send a 117 * KEY_SWITCHVIDEOMODE evdev event, which causes the desktop settings 118 * daemons like gnome-setting-daemon to switch mode and this impacts 119 * the notebooks having external HDMI connected. 120 */ 121 return NOTIFY_BAD; 122 } 123 124 return NOTIFY_DONE; 125 } 126 127 NV_STATUS NV_API_CALL nv_acpi_get_powersource(NvU32 *ac_plugged) 128 { 129 unsigned long long val; 130 int status = 0; 131 132 if (!ac_plugged) 133 return NV_ERR_INVALID_ARGUMENT; 134 135 if (!psr_device_handle) 136 return NV_ERR_INVALID_ARGUMENT; 137 138 // Check whether or not AC power is plugged in 139 status = acpi_evaluate_integer(psr_device_handle, "_PSR", NULL, &val); 140 if (ACPI_FAILURE(status)) 141 return NV_ERR_GENERIC; 142 143 // AC Power Source Plug State 144 // - 0x0 unplugged 145 // - 0x1 plugged 146 *ac_plugged = (val == 0x1); 147 148 return NV_OK; 149 } 150 151 #define ACPI_POWER_SOURCE_CHANGE_EVENT 0x80 152 static void nv_acpi_powersource_hotplug_event(acpi_handle handle, u32 event_type, void *data) 153 { 154 /* 155 * This function will handle acpi events from the linux kernel, used 156 * to detect notifications from Power Source device 157 */ 158 nv_acpi_t *pNvAcpiObject = data; 159 u32 ac_plugged = 0; 160 161 if (event_type == ACPI_POWER_SOURCE_CHANGE_EVENT) 162 { 163 if (nv_acpi_get_powersource(&ac_plugged) != NV_OK) 164 return; 165 166 rm_power_source_change_event(pNvAcpiObject->sp, !ac_plugged); 167 } 168 } 169 170 static void nv_acpi_nvpcf_event(acpi_handle handle, u32 event_type, void *data) 171 { 172 nv_acpi_t *pNvAcpiObject = data; 173 174 if (event_type == ACPI_NVPCF_EVENT_CHANGE) 175 { 176 rm_acpi_nvpcf_notify(pNvAcpiObject->sp); 177 } 178 else 179 { 180 nv_printf(NV_DBG_INFO,"NVRM: %s: NVPCF event 0x%x is not supported\n", event_type, __FUNCTION__); 181 } 182 } 183 184 /* 185 * End of ACPI event handler functions 186 */ 187 188 /* Do the necessary allocations and install notifier "handler" on the device-node "device" */ 189 static nv_acpi_t* nv_install_notifier( 190 struct acpi_handle *handle, 191 acpi_notify_handler handler, 192 void *notifier_data 193 ) 194 { 195 nvidia_stack_t *sp = NULL; 196 nv_acpi_t *pNvAcpiObject = NULL; 197 NV_STATUS rmStatus = NV_ERR_GENERIC; 198 acpi_status status = -1; 199 200 if (!handle) 201 return NULL; 202 203 if (nv_kmem_cache_alloc_stack(&sp) != 0) 204 { 205 return NULL; 206 } 207 208 rmStatus = os_alloc_mem((void **) &pNvAcpiObject, sizeof(nv_acpi_t)); 209 if (rmStatus != NV_OK) 210 goto return_error; 211 212 os_mem_set((void *)pNvAcpiObject, 0, sizeof(nv_acpi_t)); 213 214 // store a handle reference in our object 215 pNvAcpiObject->handle = handle; 216 pNvAcpiObject->sp = sp; 217 pNvAcpiObject->notifier_data = notifier_data; 218 219 status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY, 220 handler, pNvAcpiObject); 221 if (!ACPI_FAILURE(status)) 222 { 223 pNvAcpiObject->notify_handler_installed = 1; 224 225 return pNvAcpiObject; 226 } 227 228 return_error: 229 nv_kmem_cache_free_stack(sp); 230 if (pNvAcpiObject) 231 os_free_mem((void *)pNvAcpiObject); 232 233 return NULL; 234 } 235 236 /* Tear-down and remove whatever nv_install_notifier did */ 237 static void nv_uninstall_notifier(nv_acpi_t *pNvAcpiObject, acpi_notify_handler handler) 238 { 239 acpi_status status; 240 241 if (pNvAcpiObject && pNvAcpiObject->notify_handler_installed) 242 { 243 status = acpi_remove_notify_handler(pNvAcpiObject->handle, ACPI_DEVICE_NOTIFY, handler); 244 if (ACPI_FAILURE(status)) 245 { 246 nv_printf(NV_DBG_INFO, 247 "NVRM: nv_acpi_methods_uninit: failed to remove event notification handler (%d)!\n", status); 248 } 249 else 250 { 251 nv_kmem_cache_free_stack(pNvAcpiObject->sp); 252 os_free_mem((void *)pNvAcpiObject); 253 } 254 } 255 256 return; 257 } 258 259 static void nv_acpi_notify_event(acpi_handle handle, u32 event_type, void *data) 260 { 261 nv_acpi_t *pNvAcpiObject = data; 262 nv_state_t *nvl = pNvAcpiObject->notifier_data; 263 264 /* 265 * Function to handle device specific ACPI events such as display hotplug, 266 * GPS and D-notifier events. 267 */ 268 rm_acpi_notify(pNvAcpiObject->sp, NV_STATE_PTR(nvl), event_type); 269 } 270 271 void nv_acpi_register_notifier(nv_linux_state_t *nvl) 272 { 273 acpi_handle dev_handle = NULL; 274 275 /* Install the ACPI notifier corresponding to dGPU ACPI device. */ 276 if ((nvl->nv_acpi_object == NULL) && 277 nv_acpi_get_device_handle(NV_STATE_PTR(nvl), &dev_handle) && 278 (dev_handle != NULL)) 279 { 280 nvl->nv_acpi_object = nv_install_notifier(dev_handle, nv_acpi_notify_event, nvl); 281 if (nvl->nv_acpi_object == NULL) 282 { 283 nv_printf(NV_DBG_ERRORS, 284 "NVRM: nv_acpi_register_notifier: failed to install notifier\n"); 285 } 286 } 287 288 nvl->acpi_nb.notifier_call = nv_acpi_notifier_call_chain_handler; 289 register_acpi_notifier(&nvl->acpi_nb); 290 } 291 292 void nv_acpi_unregister_notifier(nv_linux_state_t *nvl) 293 { 294 unregister_acpi_notifier(&nvl->acpi_nb); 295 if (nvl->nv_acpi_object != NULL) 296 { 297 nv_uninstall_notifier(nvl->nv_acpi_object, nv_acpi_notify_event); 298 nvl->nv_acpi_object = NULL; 299 } 300 } 301 302 /* 303 * acpi methods init function. 304 * check if the NVIF, _DSM and WMMX methods are present in the acpi namespace. 305 * store NVIF, _DSM and WMMX handle if found. 306 */ 307 308 void NV_API_CALL nv_acpi_methods_init(NvU32 *handlesPresent) 309 { 310 if (!handlesPresent) // Caller passed us invalid pointer. 311 return; 312 313 *handlesPresent = 0; 314 315 NV_ACPI_WALK_NAMESPACE(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 316 ACPI_UINT32_MAX, nv_acpi_find_methods, NULL, NULL); 317 318 if (nvif_handle) 319 { 320 *handlesPresent = NV_ACPI_NVIF_HANDLE_PRESENT; 321 } 322 323 if (wmmx_handle) 324 *handlesPresent = *handlesPresent | NV_ACPI_WMMX_HANDLE_PRESENT; 325 326 if (psr_handle) 327 { 328 // Since _PSR is not a per-GPU construct we only need to register a 329 // single notifier for the _PSR event. Skip registration for subsequent 330 // devices 331 if (psr_nv_acpi_object == NULL) 332 { 333 psr_nv_acpi_object = nv_install_notifier(psr_device_handle, nv_acpi_powersource_hotplug_event, NULL); 334 } 335 } 336 337 if (nvpcf_handle && (nvpcf_nv_acpi_object == NULL)) 338 { 339 nvpcf_nv_acpi_object = nv_install_notifier(nvpcf_device_handle, nv_acpi_nvpcf_event, NULL); 340 } 341 342 return; 343 } 344 345 acpi_status nv_acpi_find_methods( 346 acpi_handle handle, 347 u32 nest_level, 348 void *dummy1, 349 void **dummy2 350 ) 351 { 352 acpi_handle method_handle; 353 354 if (!acpi_get_handle(handle, "NVIF", &method_handle)) 355 { 356 nvif_handle = method_handle; 357 } 358 359 if (!acpi_get_handle(handle, "WMMX", &method_handle)) 360 { 361 wmmx_handle = method_handle; 362 } 363 364 if (!acpi_get_handle(handle, "_PSR", &method_handle)) 365 { 366 psr_handle = method_handle; 367 psr_device_handle = handle; 368 } 369 370 if (!acpi_get_handle(handle, "NPCF", &method_handle)) 371 { 372 nvpcf_handle = method_handle; 373 nvpcf_device_handle = handle; 374 } 375 376 return 0; 377 } 378 379 void NV_API_CALL nv_acpi_methods_uninit(void) 380 { 381 nvif_handle = NULL; 382 wmmx_handle = NULL; 383 384 if (psr_nv_acpi_object != NULL) 385 { 386 nv_uninstall_notifier(psr_nv_acpi_object, nv_acpi_powersource_hotplug_event); 387 388 psr_handle = NULL; 389 psr_device_handle = NULL; 390 psr_nv_acpi_object = NULL; 391 } 392 393 if (nvpcf_nv_acpi_object != NULL) 394 { 395 nv_uninstall_notifier(nvpcf_nv_acpi_object, nv_acpi_nvpcf_event); 396 397 nvpcf_handle = NULL; 398 nvpcf_device_handle = NULL; 399 nvpcf_nv_acpi_object = NULL; 400 } 401 } 402 403 static NV_STATUS nv_acpi_extract_integer( 404 const union acpi_object *acpi_object, 405 void *buffer, 406 NvU32 buffer_size, 407 NvU32 *data_size 408 ) 409 { 410 if (acpi_object->type != ACPI_TYPE_INTEGER) 411 return NV_ERR_INVALID_ARGUMENT; 412 413 if (acpi_object->integer.value & ~0xffffffffULL) 414 *data_size = sizeof(acpi_object->integer.value); 415 else 416 *data_size = sizeof(NvU32); 417 418 if ((buffer_size < sizeof(NvU32)) || 419 ((buffer_size < sizeof(acpi_object->integer.value)) && 420 (acpi_object->integer.value & ~0xffffffffULL))) 421 { 422 return NV_ERR_BUFFER_TOO_SMALL; 423 } 424 425 memcpy(buffer, &acpi_object->integer.value, *data_size); 426 427 return NV_OK; 428 } 429 430 static NV_STATUS nv_acpi_extract_buffer( 431 const union acpi_object *acpi_object, 432 void *buffer, 433 NvU32 buffer_size, 434 NvU32 *data_size 435 ) 436 { 437 if (acpi_object->type != ACPI_TYPE_BUFFER) 438 return NV_ERR_INVALID_ARGUMENT; 439 440 *data_size = acpi_object->buffer.length; 441 442 if (buffer_size < acpi_object->buffer.length) 443 return NV_ERR_BUFFER_TOO_SMALL; 444 445 memcpy(buffer, acpi_object->buffer.pointer, *data_size); 446 447 return NV_OK; 448 } 449 450 static NV_STATUS nv_acpi_extract_package( 451 const union acpi_object *acpi_object, 452 void *buffer, 453 NvU32 buffer_size, 454 NvU32 *data_size 455 ) 456 { 457 NV_STATUS status = NV_OK; 458 NvU32 i, element_size = 0; 459 460 if (acpi_object->type != ACPI_TYPE_PACKAGE) 461 return NV_ERR_INVALID_ARGUMENT; 462 463 *data_size = 0; 464 for (i = 0; i < acpi_object->package.count; i++) 465 { 466 buffer = ((char *)buffer + element_size); 467 buffer_size -= element_size; 468 469 status = nv_acpi_extract_object(&acpi_object->package.elements[i], 470 buffer, buffer_size, &element_size); 471 if (status != NV_OK) 472 break; 473 474 *data_size += element_size; 475 } 476 477 return status; 478 } 479 480 static NV_STATUS nv_acpi_extract_object( 481 const union acpi_object *acpi_object, 482 void *buffer, 483 NvU32 buffer_size, 484 NvU32 *data_size 485 ) 486 { 487 NV_STATUS status; 488 489 switch (acpi_object->type) 490 { 491 case ACPI_TYPE_INTEGER: 492 status = nv_acpi_extract_integer(acpi_object, buffer, 493 buffer_size, data_size); 494 break; 495 496 case ACPI_TYPE_BUFFER: 497 status = nv_acpi_extract_buffer(acpi_object, buffer, 498 buffer_size, data_size); 499 break; 500 501 case ACPI_TYPE_PACKAGE: 502 status = nv_acpi_extract_package(acpi_object, buffer, 503 buffer_size, data_size); 504 break; 505 506 case ACPI_TYPE_ANY: 507 /* 508 * ACPI_TYPE_ANY is used to represent a NULL/Uninitialized object which is objectType 0 509 * in the ACPI SPEC. This should not be treated as error. 510 */ 511 status = NV_OK; 512 break; 513 514 default: 515 status = NV_ERR_NOT_SUPPORTED; 516 } 517 518 return status; 519 } 520 521 NV_STATUS NV_API_CALL nv_acpi_method( 522 NvU32 acpi_method, 523 NvU32 function, 524 NvU32 subFunction, 525 void *inParams, 526 NvU16 inParamSize, 527 NvU32 *outStatus, 528 void *outData, 529 NvU16 *outDataSize 530 ) 531 { 532 NV_STATUS status; 533 534 switch (acpi_method) 535 { 536 case NV_EVAL_ACPI_METHOD_NVIF: 537 status = nv_acpi_nvif_method(function, 538 subFunction, 539 inParams, 540 inParamSize, 541 outStatus, 542 outData, 543 outDataSize); 544 break; 545 546 case NV_EVAL_ACPI_METHOD_WMMX: 547 status = nv_acpi_wmmx_method(function, outData, outDataSize); 548 break; 549 550 default: 551 status = NV_ERR_NOT_SUPPORTED; 552 } 553 554 return status; 555 } 556 557 /* 558 * This function executes an NVIF ACPI method. 559 */ 560 static NV_STATUS nv_acpi_nvif_method( 561 NvU32 function, 562 NvU32 subFunction, 563 void *inParams, 564 NvU16 inParamSize, 565 NvU32 *outStatus, 566 void *outData, 567 NvU16 *outDataSize 568 ) 569 { 570 acpi_status status; 571 struct acpi_object_list input; 572 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 573 union acpi_object *nvif = NULL; 574 union acpi_object nvif_params[3]; 575 NvU16 localOutDataSize; 576 NvU8 localInParams[8]; 577 578 if (!nvif_handle) 579 return NV_ERR_NOT_SUPPORTED; 580 581 if (!NV_MAY_SLEEP()) 582 { 583 #if defined(DEBUG) 584 nv_printf(NV_DBG_ERRORS, 585 "NVRM: nv_acpi_nvif_method: invalid context!\n"); 586 #endif 587 return NV_ERR_NOT_SUPPORTED; 588 } 589 590 nvif_params[0].integer.type = ACPI_TYPE_INTEGER; 591 nvif_params[0].integer.value = function; 592 593 nvif_params[1].integer.type = ACPI_TYPE_INTEGER; 594 nvif_params[1].integer.value = subFunction; 595 596 nvif_params[2].buffer.type = ACPI_TYPE_BUFFER; 597 598 if (inParams && (inParamSize > 0)) 599 { 600 nvif_params[2].buffer.length = inParamSize; 601 nvif_params[2].buffer.pointer = inParams; 602 } 603 else 604 { 605 memset(localInParams, 0, 8); 606 nvif_params[2].buffer.length = 8; 607 nvif_params[2].buffer.pointer = localInParams; 608 } 609 610 input.count = 3; 611 input.pointer = nvif_params; 612 613 status = acpi_evaluate_object(nvif_handle, NULL, &input, &output); 614 if (ACPI_FAILURE(status)) 615 { 616 nv_printf(NV_DBG_INFO, 617 "NVRM: nv_acpi_nvif_method: failed to get NVIF data, " 618 "status 0x%x, function 0x%x, subFunction 0x%x!\n", 619 status, function, subFunction); 620 return NV_ERR_GENERIC; 621 } 622 623 nvif = output.pointer; 624 if (nvif && (nvif->type == ACPI_TYPE_BUFFER) && (nvif->buffer.length >= 4)) 625 { 626 if (outStatus) 627 { 628 *outStatus = nvif->buffer.pointer[3] << 24 | 629 nvif->buffer.pointer[2] << 16 | 630 nvif->buffer.pointer[1] << 8 | 631 nvif->buffer.pointer[0]; 632 } 633 634 if (outData && outDataSize) 635 { 636 localOutDataSize = nvif->buffer.length - 4; 637 if (localOutDataSize <= *outDataSize) 638 { 639 *outDataSize = NV_MIN(*outDataSize, localOutDataSize); 640 memcpy(outData, &nvif->buffer.pointer[4], *outDataSize); 641 } 642 else 643 { 644 *outDataSize = localOutDataSize; 645 kfree(output.pointer); 646 return NV_ERR_BUFFER_TOO_SMALL; 647 } 648 } 649 } 650 else 651 { 652 nv_printf(NV_DBG_INFO, 653 "NVRM: nv_acpi_nvif_method: NVIF data invalid, function 0x%x, " 654 "subFunction 0x%x!\n", function, subFunction); 655 kfree(output.pointer); 656 return NV_ERR_GENERIC; 657 } 658 659 kfree(output.pointer); 660 return NV_OK; 661 } 662 663 #define MAX_INPUT_PARAM_SIZE 1024 664 /* 665 * This function executes a _DSM ACPI method. 666 */ 667 NV_STATUS NV_API_CALL nv_acpi_dsm_method( 668 nv_state_t *nv, 669 NvU8 *pAcpiDsmGuid, 670 NvU32 acpiDsmRev, 671 NvBool acpiNvpcfDsmFunction, 672 NvU32 acpiDsmSubFunction, 673 void *pInParams, 674 NvU16 inParamSize, 675 NvU32 *outStatus, 676 void *pOutData, 677 NvU16 *pSize 678 ) 679 { 680 NV_STATUS status = NV_ERR_OPERATING_SYSTEM; 681 acpi_status acpi_status; 682 struct acpi_object_list input; 683 union acpi_object *dsm = NULL; 684 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 685 union acpi_object dsm_params[4]; 686 NvU8 *argument3 = NULL; 687 NvU32 data_size; 688 acpi_handle dev_handle = NULL; 689 690 if (!nv_acpi_get_device_handle(nv, &dev_handle)) 691 return NV_ERR_NOT_SUPPORTED; 692 693 if (!dev_handle) 694 return NV_ERR_INVALID_ARGUMENT; 695 696 if ((!pInParams) || (inParamSize > MAX_INPUT_PARAM_SIZE) || (!pOutData) || (!pSize)) 697 { 698 nv_printf(NV_DBG_INFO, 699 "NVRM: %s: invalid argument(s)!\n", __FUNCTION__); 700 return NV_ERR_INVALID_ARGUMENT; 701 } 702 703 if (!NV_MAY_SLEEP()) 704 { 705 #if defined(DEBUG) 706 nv_printf(NV_DBG_INFO, 707 "NVRM: %s: invalid argument(s)!\n", __FUNCTION__); 708 #endif 709 return NV_ERR_NOT_SUPPORTED; 710 } 711 712 status = os_alloc_mem((void **)&argument3, inParamSize); 713 if (status != NV_OK) 714 return status; 715 716 // 717 // dsm_params[0].buffer.pointer and dsm_params[1].integer.value set in 718 // switch below based on acpiDsmFunction 719 // 720 721 dsm_params[0].buffer.type = ACPI_TYPE_BUFFER; 722 dsm_params[0].buffer.length = 0x10; 723 dsm_params[0].buffer.pointer = pAcpiDsmGuid; 724 725 dsm_params[1].integer.type = ACPI_TYPE_INTEGER; 726 dsm_params[1].integer.value = acpiDsmRev; 727 728 dsm_params[2].integer.type = ACPI_TYPE_INTEGER; 729 dsm_params[2].integer.value = acpiDsmSubFunction; 730 731 dsm_params[3].buffer.type = ACPI_TYPE_BUFFER; 732 dsm_params[3].buffer.length = inParamSize; 733 memcpy(argument3, pInParams, dsm_params[3].buffer.length); 734 dsm_params[3].buffer.pointer = argument3; 735 736 // parameters for dsm calls (GUID, rev, subfunction, data) 737 input.count = 4; 738 input.pointer = dsm_params; 739 740 if (acpiNvpcfDsmFunction) 741 { 742 // 743 // acpi_evaluate_object() can operate with either valid object pathname or 744 // valid object handle. For NVPCF DSM function, use valid pathname as we do 745 // not have device handle for NVPCF device 746 // 747 dev_handle = NULL; 748 acpi_status = acpi_evaluate_object(dev_handle, "\\_SB.NPCF._DSM", &input, &output); 749 } 750 else 751 { 752 acpi_status = acpi_evaluate_object(dev_handle, "_DSM", &input, &output); 753 } 754 755 if (ACPI_FAILURE(acpi_status)) 756 { 757 nv_printf(NV_DBG_INFO, 758 "NVRM: %s: failed to evaluate _DSM method!\n", __FUNCTION__); 759 goto exit; 760 } 761 762 dsm = output.pointer; 763 if (dsm != NULL) 764 { 765 if (outStatus) 766 { 767 *outStatus = dsm->buffer.pointer[3] << 24 | 768 dsm->buffer.pointer[2] << 16 | 769 dsm->buffer.pointer[1] << 8 | 770 dsm->buffer.pointer[0]; 771 } 772 773 status = nv_acpi_extract_object(dsm, pOutData, *pSize, &data_size); 774 *pSize = data_size; 775 776 kfree(output.pointer); 777 } 778 if (status != NV_OK) 779 { 780 nv_printf(NV_DBG_ERRORS, 781 "NVRM: %s: DSM data invalid!\n", __FUNCTION__); 782 } 783 784 exit: 785 os_free_mem(argument3); 786 return status; 787 } 788 789 /* 790 * This function executes a _DDC ACPI method. 791 */ 792 NV_STATUS NV_API_CALL nv_acpi_ddc_method( 793 nv_state_t *nv, 794 void *pEdidBuffer, 795 NvU32 *pSize, 796 NvBool bReadMultiBlock 797 ) 798 { 799 acpi_status status; 800 union acpi_object *ddc = NULL; 801 NvU32 i, largestEdidSize; 802 acpi_handle dev_handle = NULL; 803 acpi_handle lcd_dev_handle = NULL; 804 acpi_handle handle = NULL; 805 806 if (!nv_acpi_get_device_handle(nv, &dev_handle)) 807 return NV_ERR_NOT_SUPPORTED; 808 809 if (!dev_handle) 810 return NV_ERR_INVALID_ARGUMENT; 811 812 if (!NV_MAY_SLEEP()) 813 { 814 #if defined(DEBUG) 815 nv_printf(NV_DBG_ERRORS, 816 "NVRM: %s: invalid context!\n", 817 __FUNCTION__); 818 #endif 819 return NV_ERR_NOT_SUPPORTED; 820 } 821 822 while (lcd_dev_handle == NULL) 823 { 824 unsigned long long device_id = 0; 825 826 status = acpi_get_next_object(ACPI_TYPE_DEVICE, dev_handle, 827 handle, &handle); 828 if (ACPI_FAILURE(status) || (handle == NULL)) 829 break; 830 831 status = acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); 832 if (ACPI_FAILURE(status)) 833 /* Couldnt query device_id for this device */ 834 continue; 835 836 switch (device_id & 0xffff) { 837 case 0x0110: 838 case 0x0118: 839 case 0x0400: 840 case 0xA420: 841 lcd_dev_handle = handle; 842 nv_printf(NV_DBG_INFO, "NVRM: %s Found LCD: %x\n", 843 __FUNCTION__, device_id); 844 break; 845 default: 846 break; 847 } 848 } 849 850 if (lcd_dev_handle == NULL) 851 { 852 nv_printf(NV_DBG_INFO, "NVRM: %s LCD not found\n", __FUNCTION__); 853 return NV_ERR_GENERIC; 854 } 855 856 // 857 // As per ACPI Spec 3.0: 858 // ARG0 = 0x1 for 128 bytes edid buffer 859 // ARG0 = 0x2 for 256 bytes edid buffer 860 // 861 862 largestEdidSize = bReadMultiBlock ? 2 : 1; 863 864 for (i = largestEdidSize; i >= 1; i--) 865 { 866 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 867 union acpi_object ddc_arg0 = { ACPI_TYPE_INTEGER }; 868 struct acpi_object_list input = { 1, &ddc_arg0 }; 869 870 ddc_arg0.integer.value = i; 871 status = acpi_evaluate_object(lcd_dev_handle, "_DDC", &input, &output); 872 if (ACPI_SUCCESS(status)) { 873 ddc = output.pointer; 874 break; 875 } 876 } 877 878 if (ACPI_FAILURE(status)) 879 { 880 nv_printf(NV_DBG_INFO, 881 "NVRM: %s: failed status: %08x \n", 882 __FUNCTION__, 883 status); 884 return NV_ERR_GENERIC; 885 } 886 else 887 { 888 if (ddc && (ddc->type == ACPI_TYPE_BUFFER) && (ddc->buffer.length > 0)) 889 { 890 if (ddc->buffer.length <= *pSize) 891 { 892 *pSize = NV_MIN(*pSize, ddc->buffer.length); 893 memcpy(pEdidBuffer, ddc->buffer.pointer, *pSize); 894 } 895 else 896 { 897 kfree(ddc); 898 return NV_ERR_BUFFER_TOO_SMALL; 899 } 900 } 901 } 902 903 kfree(ddc); 904 return NV_OK; 905 } 906 907 /* 908 * This function executes a _ROM ACPI method. 909 */ 910 NV_STATUS NV_API_CALL nv_acpi_rom_method( 911 nv_state_t *nv, 912 NvU32 *pInData, 913 NvU32 *pOutData 914 ) 915 { 916 acpi_status status; 917 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 918 union acpi_object *rom; 919 union acpi_object rom_arg[2]; 920 struct acpi_object_list input = { 2, rom_arg }; 921 acpi_handle dev_handle = NULL; 922 uint32_t offset, length; 923 924 if (!nv_acpi_get_device_handle(nv, &dev_handle)) 925 return NV_ERR_NOT_SUPPORTED; 926 927 if (!dev_handle) 928 return NV_ERR_INVALID_ARGUMENT; 929 930 if (!NV_MAY_SLEEP()) 931 { 932 #if defined(DEBUG) 933 nv_printf(NV_DBG_ERRORS, 934 "NVRM: %s: invalid context!\n", __FUNCTION__); 935 #endif 936 return NV_ERR_NOT_SUPPORTED; 937 } 938 939 offset = pInData[0]; 940 length = pInData[1]; 941 942 rom_arg[0].type = ACPI_TYPE_INTEGER; 943 rom_arg[0].integer.value = offset; 944 rom_arg[1].type = ACPI_TYPE_INTEGER; 945 rom_arg[1].integer.value = length; 946 947 status = acpi_evaluate_object(dev_handle, "_ROM", &input, &output); 948 if (ACPI_FAILURE(status)) 949 { 950 nv_printf(NV_DBG_INFO, 951 "NVRM: %s: failed to evaluate _ROM method!\n", __FUNCTION__); 952 return NV_ERR_GENERIC; 953 } 954 else 955 { 956 rom = output.pointer; 957 958 if ((rom != NULL) && (rom->type == ACPI_TYPE_BUFFER) && 959 (rom->buffer.length >= length)) 960 { 961 memcpy(pOutData, rom->buffer.pointer, length); 962 } 963 else 964 { 965 nv_printf(NV_DBG_INFO, 966 "NVRM: %s: Invalid _ROM data\n", __FUNCTION__); 967 kfree(output.pointer); 968 return NV_ERR_GENERIC; 969 } 970 } 971 972 kfree(output.pointer); 973 return NV_OK; 974 } 975 976 /* 977 * This function executes a _DOD ACPI method. 978 */ 979 NV_STATUS NV_API_CALL nv_acpi_dod_method( 980 nv_state_t *nv, 981 NvU32 *pOutData, 982 NvU32 *pSize 983 ) 984 { 985 acpi_status status; 986 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 987 union acpi_object *dod; 988 acpi_handle dev_handle = NULL; 989 NvU32 i, count = (*pSize / sizeof(NvU32)); 990 991 if (!nv_acpi_get_device_handle(nv, &dev_handle)) 992 return NV_ERR_NOT_SUPPORTED; 993 994 if (!dev_handle) 995 return NV_ERR_INVALID_ARGUMENT; 996 997 if (!NV_MAY_SLEEP()) 998 { 999 #if defined(DEBUG) 1000 nv_printf(NV_DBG_ERRORS, 1001 "NVRM: %s: invalid context!\n", __FUNCTION__); 1002 #endif 1003 return NV_ERR_NOT_SUPPORTED; 1004 } 1005 1006 status = acpi_evaluate_object(dev_handle, "_DOD", NULL, &output); 1007 1008 if (ACPI_FAILURE(status)) 1009 { 1010 nv_printf(NV_DBG_INFO, 1011 "NVRM: %s: failed to evaluate _DOD method!\n", __FUNCTION__); 1012 return NV_ERR_GENERIC; 1013 } 1014 else 1015 { 1016 dod = output.pointer; 1017 *pSize = 0; 1018 1019 if ((dod != NULL) && (dod->type == ACPI_TYPE_PACKAGE) && 1020 (dod->package.count <= count)) 1021 { 1022 for (i = 0; i < dod->package.count; i++) 1023 { 1024 if (dod->package.elements[i].type != ACPI_TYPE_INTEGER) 1025 { 1026 nv_printf(NV_DBG_INFO, 1027 "NVRM: %s: _DOD entry invalid!\n", __FUNCTION__); 1028 kfree(output.pointer); 1029 return NV_ERR_GENERIC; 1030 } 1031 1032 pOutData[i] = dod->package.elements[i].integer.value; 1033 *pSize += sizeof(NvU32); 1034 } 1035 } 1036 else 1037 { 1038 nv_printf(NV_DBG_INFO, 1039 "NVRM: %s: _DOD data too large!\n", __FUNCTION__); 1040 kfree(output.pointer); 1041 return NV_ERR_GENERIC; 1042 } 1043 } 1044 1045 kfree(output.pointer); 1046 return NV_OK; 1047 } 1048 1049 /* 1050 * This function executes a WMMX ACPI method. 1051 */ 1052 static NV_STATUS nv_acpi_wmmx_method( 1053 NvU32 arg2, 1054 NvU8 *outData, 1055 NvU16 *outDataSize 1056 ) 1057 { 1058 acpi_status status; 1059 struct acpi_object_list input; 1060 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1061 union acpi_object *mmx = NULL; 1062 union acpi_object mmx_params[3]; 1063 1064 if (!wmmx_handle) 1065 return NV_ERR_NOT_SUPPORTED; 1066 1067 if (!NV_MAY_SLEEP()) 1068 { 1069 #if defined(DEBUG) 1070 nv_printf(NV_DBG_ERRORS, 1071 "NVRM: nv_acpi_wmmx_method: invalid context!\n"); 1072 #endif 1073 return NV_ERR_NOT_SUPPORTED; 1074 } 1075 1076 /* argument 0 and argument 1 are not used in WMMX method, passing 0 */ 1077 1078 mmx_params[0].integer.type = ACPI_TYPE_INTEGER; 1079 mmx_params[0].integer.value = 0; 1080 1081 mmx_params[1].integer.type = ACPI_TYPE_INTEGER; 1082 mmx_params[1].integer.value = 0; 1083 1084 mmx_params[2].integer.type = ACPI_TYPE_INTEGER; 1085 mmx_params[2].integer.value = arg2; 1086 1087 input.count = 3; 1088 input.pointer = mmx_params; 1089 1090 status = acpi_evaluate_object(wmmx_handle, NULL, &input, &output); 1091 if (ACPI_FAILURE(status)) 1092 { 1093 nv_printf(NV_DBG_INFO, 1094 "NVRM: nv_acpi_wmmx_method: failed to get WMMX data, " 1095 "status 0x%x!\n", status); 1096 return NV_ERR_GENERIC; 1097 } 1098 1099 mmx = output.pointer; 1100 if (mmx && (mmx->type == ACPI_TYPE_BUFFER) && (mmx->buffer.length > 0)) 1101 { 1102 if (outData && outDataSize) 1103 { 1104 if (mmx->buffer.length <= *outDataSize) 1105 { 1106 *outDataSize = NV_MIN(*outDataSize, mmx->buffer.length); 1107 memcpy(outData, mmx->buffer.pointer, *outDataSize); 1108 } 1109 else 1110 { 1111 kfree(output.pointer); 1112 return NV_ERR_BUFFER_TOO_SMALL; 1113 } 1114 } 1115 } 1116 else 1117 { 1118 nv_printf(NV_DBG_ERRORS, 1119 "NVRM: nv_acpi_wmmx_method: WMMX data invalid.\n"); 1120 kfree(output.pointer); 1121 return NV_ERR_GENERIC; 1122 } 1123 1124 kfree(output.pointer); 1125 return NV_OK; 1126 } 1127 1128 NvBool nv_acpi_power_resource_method_present( 1129 struct pci_dev *pdev 1130 ) 1131 { 1132 acpi_handle handle = NULL; 1133 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; 1134 union acpi_object *object_package, *object_reference; 1135 acpi_status status; 1136 1137 #if defined(DEVICE_ACPI_HANDLE) 1138 handle = DEVICE_ACPI_HANDLE(&pdev->dev); 1139 #elif defined (ACPI_HANDLE) 1140 handle = ACPI_HANDLE(&pdev->dev); 1141 #endif 1142 1143 if (!handle) 1144 return NV_FALSE; 1145 1146 status = acpi_evaluate_object(handle, "_PR3", NULL, &buf); 1147 if (ACPI_FAILURE(status)) 1148 { 1149 nv_printf(NV_DBG_INFO,"NVRM: Failed to evaluate _PR3 object\n"); 1150 return NV_FALSE; 1151 } 1152 1153 if (!buf.pointer) 1154 { 1155 nv_printf(NV_DBG_INFO, "NVRM: output buffer pointer is null" 1156 " for _PR3 method\n"); 1157 return NV_FALSE; 1158 } 1159 1160 object_package = buf.pointer; 1161 1162 /* 1163 * _PR3 object should be of type package and 1164 * it should contain only one reference 1165 */ 1166 if ((object_package->type != ACPI_TYPE_PACKAGE) && 1167 (object_package->package.count != 0x1)) 1168 { 1169 nv_printf(NV_DBG_ERRORS,"NVRM: _PR3 object is not a type 'package'\n"); 1170 return NV_FALSE; 1171 } 1172 1173 object_reference = object_package->package.elements; 1174 1175 /* Check for the reference and the actual type of the reference. */ 1176 if ((object_reference->reference.actual_type != ACPI_TYPE_POWER) && 1177 (object_reference->type != ACPI_TYPE_LOCAL_REFERENCE)) 1178 { 1179 nv_printf(NV_DBG_ERRORS, 1180 "NVRM: _PR3 object does not contain POWER Reference\n"); 1181 return NV_FALSE; 1182 } 1183 return NV_TRUE; 1184 } 1185 1186 /* 1187 * This function executes MUX ACPI methods. 1188 */ 1189 NV_STATUS NV_API_CALL nv_acpi_mux_method( 1190 nv_state_t *nv, 1191 NvU32 *pInOut, 1192 NvU32 muxAcpiId, 1193 const char *pMethodName 1194 ) 1195 { 1196 acpi_status status; 1197 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1198 union acpi_object *mux = NULL; 1199 union acpi_object mux_arg = { ACPI_TYPE_INTEGER }; 1200 struct acpi_object_list input = { 1, &mux_arg }; 1201 acpi_handle dev_handle = NULL; 1202 acpi_handle mux_dev_handle = NULL; 1203 acpi_handle handle = NULL; 1204 unsigned long long device_id = 0; 1205 1206 if ((strcmp(pMethodName, "MXDS") != 0) 1207 && (strcmp(pMethodName, "MXDM") != 0)) 1208 { 1209 nv_printf(NV_DBG_ERRORS, "NVRM: %s: Unsupported ACPI method %s\n", 1210 __FUNCTION__, pMethodName); 1211 return NV_ERR_NOT_SUPPORTED; 1212 } 1213 else 1214 { 1215 nv_printf(NV_DBG_INFO, "NVRM: %s: Call for %s ACPI method \n", 1216 __FUNCTION__, pMethodName); 1217 } 1218 1219 if (!nv_acpi_get_device_handle(nv, &dev_handle)) 1220 return NV_ERR_NOT_SUPPORTED; 1221 1222 if (!dev_handle) 1223 return NV_ERR_INVALID_ARGUMENT; 1224 1225 if (!NV_MAY_SLEEP()) 1226 { 1227 #if defined(DEBUG) 1228 nv_printf(NV_DBG_ERRORS, "NVRM: %s: invalid context!\n", __FUNCTION__); 1229 #endif 1230 return NV_ERR_NOT_SUPPORTED; 1231 } 1232 1233 while (mux_dev_handle == NULL) 1234 { 1235 status = acpi_get_next_object(ACPI_TYPE_DEVICE, dev_handle, 1236 handle, &handle); 1237 if (ACPI_FAILURE(status) || (handle == NULL)) 1238 break; 1239 1240 status = acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); 1241 if (ACPI_SUCCESS(status) && (device_id == muxAcpiId)) 1242 mux_dev_handle = handle; 1243 } 1244 1245 if (mux_dev_handle == NULL) 1246 { 1247 nv_printf(NV_DBG_INFO, 1248 "NVRM: %s Mux device handle not found\n", __FUNCTION__); 1249 return NV_ERR_GENERIC; 1250 } 1251 1252 mux_arg.integer.type = ACPI_TYPE_INTEGER; 1253 mux_arg.integer.value = (NvU64) *pInOut; 1254 1255 status = acpi_evaluate_object(mux_dev_handle, (acpi_string)pMethodName, 1256 &input, &output); 1257 1258 if (ACPI_FAILURE(status)) 1259 { 1260 nv_printf(NV_DBG_INFO, "NVRM: %s: Failed to evaluate %s method!\n", 1261 __FUNCTION__, pMethodName); 1262 return NV_ERR_GENERIC; 1263 } 1264 else 1265 { 1266 mux = output.pointer; 1267 1268 if (mux && (mux->type == ACPI_TYPE_INTEGER)) 1269 { 1270 *pInOut = mux->integer.value; 1271 } 1272 else 1273 { 1274 nv_printf(NV_DBG_INFO, 1275 "NVRM: %s: Invalid MUX data\n", __FUNCTION__); 1276 kfree(output.pointer); 1277 return NV_ERR_GENERIC; 1278 } 1279 } 1280 1281 kfree(output.pointer); 1282 return NV_OK; 1283 } 1284 1285 static acpi_status nv_acpi_find_battery_info( 1286 acpi_handle handle, 1287 NvBool bUseBix 1288 ) 1289 { 1290 acpi_status status = AE_OK; 1291 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; 1292 union acpi_object *object_package; 1293 NvU32 battery_technology_offset; 1294 1295 status = acpi_evaluate_object(handle, NULL, NULL, &buf); 1296 1297 if (ACPI_FAILURE(status)) 1298 { 1299 nv_printf(NV_DBG_INFO, "NVRM: Failed to evaluate battery's object\n"); 1300 return AE_OK; 1301 } 1302 1303 if (!buf.pointer) 1304 { 1305 nv_printf(NV_DBG_INFO, "NVRM: Battery object output buffer is null\n"); 1306 return AE_OK; 1307 } 1308 1309 object_package = buf.pointer; 1310 1311 if (object_package->type != ACPI_TYPE_PACKAGE) 1312 { 1313 nv_printf(NV_DBG_INFO, "NVRM: Battery method output is not package\n"); 1314 return AE_OK; 1315 } 1316 1317 if (bUseBix) 1318 { 1319 battery_technology_offset = BIX_BATTERY_TECHNOLOGY_OFFSET; 1320 } 1321 else 1322 { 1323 battery_technology_offset = BIF_BATTERY_TECHNOLOGY_OFFSET; 1324 } 1325 1326 /* 1327 * Only checking here for Battery technology type. 1328 * Other fields like Battery Model/Serial number could also be checked but 1329 * driver need to support the case where user has removed battery from the 1330 * system. 1331 * _STA method on the battery device handle couldn't be used due to the same 1332 * reason. 1333 * Hence just cheking if battery technology of slot is rechargable or not. 1334 */ 1335 1336 if ((object_package->package.elements[battery_technology_offset].type != ACPI_TYPE_INTEGER) || 1337 (object_package->package.elements[battery_technology_offset].integer.value != BATTERY_RECHARGABLE)) 1338 { 1339 return AE_OK; 1340 } 1341 1342 battery_present = NV_TRUE; 1343 1344 /* Stop traversing acpi tree. */ 1345 return AE_CTRL_TERMINATE; 1346 } 1347 1348 static acpi_status nv_acpi_find_battery_device( 1349 acpi_handle handle, 1350 u32 nest_level, 1351 void *dummy1, 1352 void **dummy2 1353 ) 1354 { 1355 acpi_handle bif_method_handle; 1356 acpi_handle bix_method_handle; 1357 acpi_status status = AE_OK; 1358 1359 // Find method Battery Information /Extended/ (_BIX or _BIF) and then Battery type. 1360 if (!acpi_get_handle(handle, "_BIX", &bix_method_handle)) 1361 { 1362 status = nv_acpi_find_battery_info(bix_method_handle, NV_TRUE/*bUseBix*/); 1363 } 1364 1365 if ((battery_present == NV_FALSE) && 1366 !acpi_get_handle(handle, "_BIF", &bif_method_handle)) 1367 { 1368 status = nv_acpi_find_battery_info(bif_method_handle, NV_FALSE/*bUseBix*/); 1369 } 1370 1371 return status; 1372 } 1373 1374 NvBool NV_API_CALL nv_acpi_is_battery_present(void) 1375 { 1376 NV_ACPI_WALK_NAMESPACE(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1377 nv_acpi_find_battery_device, NULL, NULL); 1378 1379 if (battery_present == NV_TRUE) 1380 { 1381 return NV_TRUE; 1382 } 1383 1384 return NV_FALSE; 1385 } 1386 1387 #else // NV_LINUX_ACPI_EVENTS_SUPPORTED 1388 1389 void NV_API_CALL nv_acpi_methods_init(NvU32 *handlePresent) 1390 { 1391 *handlePresent = 0; 1392 } 1393 1394 void NV_API_CALL nv_acpi_methods_uninit(void) 1395 { 1396 return; 1397 } 1398 1399 NV_STATUS NV_API_CALL nv_acpi_method( 1400 NvU32 acpi_method, 1401 NvU32 function, 1402 NvU32 subFunction, 1403 void *inParams, 1404 NvU16 inParamSize, 1405 NvU32 *outStatus, 1406 void *outData, 1407 NvU16 *outDataSize 1408 ) 1409 { 1410 return NV_ERR_NOT_SUPPORTED; 1411 } 1412 1413 NV_STATUS NV_API_CALL nv_acpi_dsm_method( 1414 nv_state_t *nv, 1415 NvU8 *pAcpiDsmGuid, 1416 NvU32 acpiDsmRev, 1417 NvBool acpiNvpcfDsmFunction, 1418 NvU32 acpiDsmSubFunction, 1419 void *pInParams, 1420 NvU16 inParamSize, 1421 NvU32 *outStatus, 1422 void *pOutData, 1423 NvU16 *pSize 1424 ) 1425 { 1426 return NV_ERR_NOT_SUPPORTED; 1427 } 1428 1429 NV_STATUS NV_API_CALL nv_acpi_ddc_method( 1430 nv_state_t *nv, 1431 void *pEdidBuffer, 1432 NvU32 *pSize, 1433 NvBool bReadMultiBlock 1434 ) 1435 { 1436 return NV_ERR_NOT_SUPPORTED; 1437 } 1438 1439 NV_STATUS NV_API_CALL nv_acpi_rom_method( 1440 nv_state_t *nv, 1441 NvU32 *pInData, 1442 NvU32 *pOutData 1443 ) 1444 { 1445 return NV_ERR_NOT_SUPPORTED; 1446 } 1447 1448 NV_STATUS NV_API_CALL nv_acpi_dod_method( 1449 nv_state_t *nv, 1450 NvU32 *pOutData, 1451 NvU32 *pSize 1452 ) 1453 { 1454 return NV_ERR_NOT_SUPPORTED; 1455 } 1456 1457 NvBool nv_acpi_power_resource_method_present( 1458 struct pci_dev *pdev 1459 ) 1460 { 1461 return NV_FALSE; 1462 } 1463 1464 NV_STATUS NV_API_CALL nv_acpi_get_powersource(NvU32 *ac_plugged) 1465 { 1466 return NV_ERR_NOT_SUPPORTED; 1467 } 1468 1469 void nv_acpi_register_notifier(nv_linux_state_t *nvl) 1470 { 1471 return; 1472 } 1473 1474 void nv_acpi_unregister_notifier(nv_linux_state_t *nvl) 1475 { 1476 return; 1477 } 1478 1479 NV_STATUS NV_API_CALL nv_acpi_mux_method( 1480 nv_state_t *nv, 1481 NvU32 *pInOut, 1482 NvU32 muxAcpiId, 1483 const char *pMethodName 1484 ) 1485 { 1486 return NV_ERR_NOT_SUPPORTED; 1487 } 1488 1489 NvBool NV_API_CALL nv_acpi_is_battery_present(void) 1490 { 1491 return NV_FALSE; 1492 } 1493 #endif 1494