1 /* $OpenBSD: radeon_acpi.c,v 1.2 2014/02/09 11:03:31 jsg Exp $ */ 2 /* 3 * Copyright 2012 Advanced Micro Devices, Inc. 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 */ 24 25 #include <dev/pci/drm/drmP.h> 26 #include <dev/pci/drm/drm_crtc_helper.h> 27 #include "radeon.h" 28 #include "radeon_acpi.h" 29 #include "atom.h" 30 31 #define ACPI_AC_CLASS "ac_adapter" 32 33 extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); 34 35 struct atif_verify_interface { 36 u16 size; /* structure size in bytes (includes size field) */ 37 u16 version; /* version */ 38 u32 notification_mask; /* supported notifications mask */ 39 u32 function_bits; /* supported functions bit vector */ 40 } __packed; 41 42 struct atif_system_params { 43 u16 size; /* structure size in bytes (includes size field) */ 44 u32 valid_mask; /* valid flags mask */ 45 u32 flags; /* flags */ 46 u8 command_code; /* notify command code */ 47 } __packed; 48 49 struct atif_sbios_requests { 50 u16 size; /* structure size in bytes (includes size field) */ 51 u32 pending; /* pending sbios requests */ 52 u8 panel_exp_mode; /* panel expansion mode */ 53 u8 thermal_gfx; /* thermal state: target gfx controller */ 54 u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */ 55 u8 forced_power_gfx; /* forced power state: target gfx controller */ 56 u8 forced_power_state; /* forced power state: state id */ 57 u8 system_power_src; /* system power source */ 58 u8 backlight_level; /* panel backlight level (0-255) */ 59 } __packed; 60 61 #define ATIF_NOTIFY_MASK 0x3 62 #define ATIF_NOTIFY_NONE 0 63 #define ATIF_NOTIFY_81 1 64 #define ATIF_NOTIFY_N 2 65 66 struct atcs_verify_interface { 67 u16 size; /* structure size in bytes (includes size field) */ 68 u16 version; /* version */ 69 u32 function_bits; /* supported functions bit vector */ 70 } __packed; 71 72 /* Call the ATIF method 73 */ 74 /** 75 * radeon_atif_call - call an ATIF method 76 * 77 * @handle: acpi handle 78 * @function: the ATIF function to execute 79 * @params: ATIF function params 80 * 81 * Executes the requested ATIF function (all asics). 82 * Returns a pointer to the acpi output buffer. 83 */ 84 static union acpi_object *radeon_atif_call(acpi_handle handle, int function, 85 struct acpi_buffer *params) 86 { 87 acpi_status status; 88 union acpi_object atif_arg_elements[2]; 89 struct acpi_object_list atif_arg; 90 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 91 92 atif_arg.count = 2; 93 atif_arg.pointer = &atif_arg_elements[0]; 94 95 atif_arg_elements[0].type = ACPI_TYPE_INTEGER; 96 atif_arg_elements[0].integer.value = function; 97 98 if (params) { 99 atif_arg_elements[1].type = ACPI_TYPE_BUFFER; 100 atif_arg_elements[1].buffer.length = params->length; 101 atif_arg_elements[1].buffer.pointer = params->pointer; 102 } else { 103 /* We need a second fake parameter */ 104 atif_arg_elements[1].type = ACPI_TYPE_INTEGER; 105 atif_arg_elements[1].integer.value = 0; 106 } 107 108 status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); 109 110 /* Fail only if calling the method fails and ATIF is supported */ 111 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 112 DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", 113 acpi_format_exception(status)); 114 kfree(buffer.pointer); 115 return NULL; 116 } 117 118 return buffer.pointer; 119 } 120 121 /** 122 * radeon_atif_parse_notification - parse supported notifications 123 * 124 * @n: supported notifications struct 125 * @mask: supported notifications mask from ATIF 126 * 127 * Use the supported notifications mask from ATIF function 128 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications 129 * are supported (all asics). 130 */ 131 static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask) 132 { 133 n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED; 134 n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED; 135 n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED; 136 n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED; 137 n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED; 138 n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED; 139 n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED; 140 n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED; 141 n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED; 142 } 143 144 /** 145 * radeon_atif_parse_functions - parse supported functions 146 * 147 * @f: supported functions struct 148 * @mask: supported functions mask from ATIF 149 * 150 * Use the supported functions mask from ATIF function 151 * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions 152 * are supported (all asics). 153 */ 154 static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask) 155 { 156 f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED; 157 f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED; 158 f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED; 159 f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED; 160 f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED; 161 f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED; 162 f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED; 163 f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED; 164 f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED; 165 f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED; 166 } 167 168 /** 169 * radeon_atif_verify_interface - verify ATIF 170 * 171 * @handle: acpi handle 172 * @atif: radeon atif struct 173 * 174 * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function 175 * to initialize ATIF and determine what features are supported 176 * (all asics). 177 * returns 0 on success, error on failure. 178 */ 179 static int radeon_atif_verify_interface(acpi_handle handle, 180 struct radeon_atif *atif) 181 { 182 union acpi_object *info; 183 struct atif_verify_interface output; 184 size_t size; 185 int err = 0; 186 187 info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); 188 if (!info) 189 return -EIO; 190 191 memset(&output, 0, sizeof(output)); 192 193 size = *(u16 *) info->buffer.pointer; 194 if (size < 12) { 195 DRM_INFO("ATIF buffer is too small: %zu\n", size); 196 err = -EINVAL; 197 goto out; 198 } 199 size = min(sizeof(output), size); 200 201 memcpy(&output, info->buffer.pointer, size); 202 203 /* TODO: check version? */ 204 DRM_DEBUG_DRIVER("ATIF version %u\n", output.version); 205 206 radeon_atif_parse_notification(&atif->notifications, output.notification_mask); 207 radeon_atif_parse_functions(&atif->functions, output.function_bits); 208 209 out: 210 kfree(info); 211 return err; 212 } 213 214 /** 215 * radeon_atif_get_notification_params - determine notify configuration 216 * 217 * @handle: acpi handle 218 * @n: atif notification configuration struct 219 * 220 * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function 221 * to determine if a notifier is used and if so which one 222 * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n) 223 * where n is specified in the result if a notifier is used. 224 * Returns 0 on success, error on failure. 225 */ 226 static int radeon_atif_get_notification_params(acpi_handle handle, 227 struct radeon_atif_notification_cfg *n) 228 { 229 union acpi_object *info; 230 struct atif_system_params params; 231 size_t size; 232 int err = 0; 233 234 info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); 235 if (!info) { 236 err = -EIO; 237 goto out; 238 } 239 240 size = *(u16 *) info->buffer.pointer; 241 if (size < 10) { 242 err = -EINVAL; 243 goto out; 244 } 245 246 memset(¶ms, 0, sizeof(params)); 247 size = min(sizeof(params), size); 248 memcpy(¶ms, info->buffer.pointer, size); 249 250 DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n", 251 params.flags, params.valid_mask); 252 params.flags = params.flags & params.valid_mask; 253 254 if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { 255 n->enabled = false; 256 n->command_code = 0; 257 } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) { 258 n->enabled = true; 259 n->command_code = 0x81; 260 } else { 261 if (size < 11) { 262 err = -EINVAL; 263 goto out; 264 } 265 n->enabled = true; 266 n->command_code = params.command_code; 267 } 268 269 out: 270 DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n", 271 (n->enabled ? "enabled" : "disabled"), 272 n->command_code); 273 kfree(info); 274 return err; 275 } 276 277 /** 278 * radeon_atif_get_sbios_requests - get requested sbios event 279 * 280 * @handle: acpi handle 281 * @req: atif sbios request struct 282 * 283 * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function 284 * to determine what requests the sbios is making to the driver 285 * (all asics). 286 * Returns 0 on success, error on failure. 287 */ 288 static int radeon_atif_get_sbios_requests(acpi_handle handle, 289 struct atif_sbios_requests *req) 290 { 291 union acpi_object *info; 292 size_t size; 293 int count = 0; 294 295 info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); 296 if (!info) 297 return -EIO; 298 299 size = *(u16 *)info->buffer.pointer; 300 if (size < 0xd) { 301 count = -EINVAL; 302 goto out; 303 } 304 memset(req, 0, sizeof(*req)); 305 306 size = min(sizeof(*req), size); 307 memcpy(req, info->buffer.pointer, size); 308 DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending); 309 310 count = hweight32(req->pending); 311 312 out: 313 kfree(info); 314 return count; 315 } 316 317 /** 318 * radeon_atif_handler - handle ATIF notify requests 319 * 320 * @rdev: radeon_device pointer 321 * @event: atif sbios request struct 322 * 323 * Checks the acpi event and if it matches an atif event, 324 * handles it. 325 * Returns NOTIFY code 326 */ 327 int radeon_atif_handler(struct radeon_device *rdev, 328 struct acpi_bus_event *event) 329 { 330 struct radeon_atif *atif = &rdev->atif; 331 struct atif_sbios_requests req; 332 acpi_handle handle; 333 int count; 334 335 DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", 336 event->device_class, event->type); 337 338 if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) 339 return NOTIFY_DONE; 340 341 if (!atif->notification_cfg.enabled || 342 event->type != atif->notification_cfg.command_code) 343 /* Not our event */ 344 return NOTIFY_DONE; 345 346 /* Check pending SBIOS requests */ 347 handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); 348 count = radeon_atif_get_sbios_requests(handle, &req); 349 350 if (count <= 0) 351 return NOTIFY_DONE; 352 353 DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count); 354 355 if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) { 356 struct radeon_encoder *enc = atif->encoder_for_bl; 357 358 if (enc) { 359 DRM_DEBUG_DRIVER("Changing brightness to %d\n", 360 req.backlight_level); 361 362 radeon_set_backlight_level(rdev, enc, req.backlight_level); 363 364 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) 365 if (rdev->is_atom_bios) { 366 struct radeon_encoder_atom_dig *dig = enc->enc_priv; 367 backlight_force_update(dig->bl_dev, 368 BACKLIGHT_UPDATE_HOTKEY); 369 } else { 370 struct radeon_encoder_lvds *dig = enc->enc_priv; 371 backlight_force_update(dig->bl_dev, 372 BACKLIGHT_UPDATE_HOTKEY); 373 } 374 #endif 375 } 376 } 377 /* TODO: check other events */ 378 379 /* We've handled the event, stop the notifier chain. The ACPI interface 380 * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to 381 * userspace if the event was generated only to signal a SBIOS 382 * request. 383 */ 384 return NOTIFY_BAD; 385 } 386 387 /* Call the ATCS method 388 */ 389 /** 390 * radeon_atcs_call - call an ATCS method 391 * 392 * @handle: acpi handle 393 * @function: the ATCS function to execute 394 * @params: ATCS function params 395 * 396 * Executes the requested ATCS function (all asics). 397 * Returns a pointer to the acpi output buffer. 398 */ 399 static union acpi_object *radeon_atcs_call(acpi_handle handle, int function, 400 struct acpi_buffer *params) 401 { 402 acpi_status status; 403 union acpi_object atcs_arg_elements[2]; 404 struct acpi_object_list atcs_arg; 405 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 406 407 atcs_arg.count = 2; 408 atcs_arg.pointer = &atcs_arg_elements[0]; 409 410 atcs_arg_elements[0].type = ACPI_TYPE_INTEGER; 411 atcs_arg_elements[0].integer.value = function; 412 413 if (params) { 414 atcs_arg_elements[1].type = ACPI_TYPE_BUFFER; 415 atcs_arg_elements[1].buffer.length = params->length; 416 atcs_arg_elements[1].buffer.pointer = params->pointer; 417 } else { 418 /* We need a second fake parameter */ 419 atcs_arg_elements[1].type = ACPI_TYPE_INTEGER; 420 atcs_arg_elements[1].integer.value = 0; 421 } 422 423 status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer); 424 425 /* Fail only if calling the method fails and ATIF is supported */ 426 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 427 DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n", 428 acpi_format_exception(status)); 429 kfree(buffer.pointer); 430 return NULL; 431 } 432 433 return buffer.pointer; 434 } 435 436 /** 437 * radeon_atcs_parse_functions - parse supported functions 438 * 439 * @f: supported functions struct 440 * @mask: supported functions mask from ATCS 441 * 442 * Use the supported functions mask from ATCS function 443 * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions 444 * are supported (all asics). 445 */ 446 static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask) 447 { 448 f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED; 449 f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED; 450 f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED; 451 f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED; 452 } 453 454 /** 455 * radeon_atcs_verify_interface - verify ATCS 456 * 457 * @handle: acpi handle 458 * @atcs: radeon atcs struct 459 * 460 * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function 461 * to initialize ATCS and determine what features are supported 462 * (all asics). 463 * returns 0 on success, error on failure. 464 */ 465 static int radeon_atcs_verify_interface(acpi_handle handle, 466 struct radeon_atcs *atcs) 467 { 468 union acpi_object *info; 469 struct atcs_verify_interface output; 470 size_t size; 471 int err = 0; 472 473 info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL); 474 if (!info) 475 return -EIO; 476 477 memset(&output, 0, sizeof(output)); 478 479 size = *(u16 *) info->buffer.pointer; 480 if (size < 8) { 481 DRM_INFO("ATCS buffer is too small: %zu\n", size); 482 err = -EINVAL; 483 goto out; 484 } 485 size = min(sizeof(output), size); 486 487 memcpy(&output, info->buffer.pointer, size); 488 489 /* TODO: check version? */ 490 DRM_DEBUG_DRIVER("ATCS version %u\n", output.version); 491 492 radeon_atcs_parse_functions(&atcs->functions, output.function_bits); 493 494 out: 495 kfree(info); 496 return err; 497 } 498 499 /** 500 * radeon_acpi_event - handle notify events 501 * 502 * @nb: notifier block 503 * @val: val 504 * @data: acpi event 505 * 506 * Calls relevant radeon functions in response to various 507 * acpi events. 508 * Returns NOTIFY code 509 */ 510 static int radeon_acpi_event(struct notifier_block *nb, 511 unsigned long val, 512 void *data) 513 { 514 struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb); 515 struct acpi_bus_event *entry = (struct acpi_bus_event *)data; 516 517 if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { 518 if (power_supply_is_system_supplied() > 0) 519 DRM_DEBUG_DRIVER("pm: AC\n"); 520 else 521 DRM_DEBUG_DRIVER("pm: DC\n"); 522 523 radeon_pm_acpi_event_handler(rdev); 524 } 525 526 /* Check for pending SBIOS requests */ 527 return radeon_atif_handler(rdev, entry); 528 } 529 530 /* Call all ACPI methods here */ 531 /** 532 * radeon_acpi_init - init driver acpi support 533 * 534 * @rdev: radeon_device pointer 535 * 536 * Verifies the AMD ACPI interfaces and registers with the acpi 537 * notifier chain (all asics). 538 * Returns 0 on success, error on failure. 539 */ 540 int radeon_acpi_init(struct radeon_device *rdev) 541 { 542 acpi_handle handle; 543 struct radeon_atif *atif = &rdev->atif; 544 struct radeon_atcs *atcs = &rdev->atcs; 545 int ret; 546 547 /* Get the device handle */ 548 handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); 549 550 /* No need to proceed if we're sure that ATIF is not supported */ 551 if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) 552 return 0; 553 554 /* Call the ATCS method */ 555 ret = radeon_atcs_verify_interface(handle, atcs); 556 if (ret) { 557 DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); 558 } 559 560 /* Call the ATIF method */ 561 ret = radeon_atif_verify_interface(handle, atif); 562 if (ret) { 563 DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); 564 goto out; 565 } 566 567 if (atif->notifications.brightness_change) { 568 struct drm_encoder *tmp; 569 struct radeon_encoder *target = NULL; 570 571 /* Find the encoder controlling the brightness */ 572 list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list, 573 head) { 574 struct radeon_encoder *enc = to_radeon_encoder(tmp); 575 576 if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) && 577 enc->enc_priv) { 578 if (rdev->is_atom_bios) { 579 struct radeon_encoder_atom_dig *dig = enc->enc_priv; 580 if (dig->bl_dev) { 581 target = enc; 582 break; 583 } 584 } else { 585 struct radeon_encoder_lvds *dig = enc->enc_priv; 586 if (dig->bl_dev) { 587 target = enc; 588 break; 589 } 590 } 591 } 592 } 593 594 atif->encoder_for_bl = target; 595 if (!target) { 596 /* Brightness change notification is enabled, but we 597 * didn't find a backlight controller, this should 598 * never happen. 599 */ 600 DRM_ERROR("Cannot find a backlight controller\n"); 601 } 602 } 603 604 if (atif->functions.sbios_requests && !atif->functions.system_params) { 605 /* XXX check this workraround, if sbios request function is 606 * present we have to see how it's configured in the system 607 * params 608 */ 609 atif->functions.system_params = true; 610 } 611 612 if (atif->functions.system_params) { 613 ret = radeon_atif_get_notification_params(handle, 614 &atif->notification_cfg); 615 if (ret) { 616 DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", 617 ret); 618 /* Disable notification */ 619 atif->notification_cfg.enabled = false; 620 } 621 } 622 623 out: 624 rdev->acpi_nb.notifier_call = radeon_acpi_event; 625 register_acpi_notifier(&rdev->acpi_nb); 626 627 return ret; 628 } 629 630 /** 631 * radeon_acpi_fini - tear down driver acpi support 632 * 633 * @rdev: radeon_device pointer 634 * 635 * Unregisters with the acpi notifier chain (all asics). 636 */ 637 void radeon_acpi_fini(struct radeon_device *rdev) 638 { 639 unregister_acpi_notifier(&rdev->acpi_nb); 640 } 641