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

drm/amdgpu/debugfs: properly handle runtime pm

If driver debugfs files are accessed, power up the GPU
when necessary.

Reviewed-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+134 -7
+126 -7
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
··· 26 26 #include <linux/kthread.h> 27 27 #include <linux/pci.h> 28 28 #include <linux/uaccess.h> 29 + #include <linux/pm_runtime.h> 29 30 30 31 #include <drm/drm_debugfs.h> 31 32 ··· 145 144 146 145 *pos &= (1UL << 22) - 1; 147 146 147 + r = pm_runtime_get_sync(adev->ddev->dev); 148 + if (r < 0) 149 + return r; 150 + 148 151 if (use_bank) { 149 152 if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || 150 - (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) 153 + (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) { 154 + pm_runtime_mark_last_busy(adev->ddev->dev); 155 + pm_runtime_put_autosuspend(adev->ddev->dev); 151 156 return -EINVAL; 157 + } 152 158 mutex_lock(&adev->grbm_idx_mutex); 153 159 amdgpu_gfx_select_se_sh(adev, se_bank, 154 160 sh_bank, instance_bank); ··· 201 193 if (pm_pg_lock) 202 194 mutex_unlock(&adev->pm.mutex); 203 195 196 + pm_runtime_mark_last_busy(adev->ddev->dev); 197 + pm_runtime_put_autosuspend(adev->ddev->dev); 198 + 204 199 return result; 205 200 } 206 201 ··· 248 237 if (size & 0x3 || *pos & 0x3) 249 238 return -EINVAL; 250 239 240 + r = pm_runtime_get_sync(adev->ddev->dev); 241 + if (r < 0) 242 + return r; 243 + 251 244 while (size) { 252 245 uint32_t value; 253 246 254 247 value = RREG32_PCIE(*pos >> 2); 255 248 r = put_user(value, (uint32_t *)buf); 256 - if (r) 249 + if (r) { 250 + pm_runtime_mark_last_busy(adev->ddev->dev); 251 + pm_runtime_put_autosuspend(adev->ddev->dev); 257 252 return r; 253 + } 258 254 259 255 result += 4; 260 256 buf += 4; 261 257 *pos += 4; 262 258 size -= 4; 263 259 } 260 + 261 + pm_runtime_mark_last_busy(adev->ddev->dev); 262 + pm_runtime_put_autosuspend(adev->ddev->dev); 264 263 265 264 return result; 266 265 } ··· 297 276 if (size & 0x3 || *pos & 0x3) 298 277 return -EINVAL; 299 278 279 + r = pm_runtime_get_sync(adev->ddev->dev); 280 + if (r < 0) 281 + return r; 282 + 300 283 while (size) { 301 284 uint32_t value; 302 285 303 286 r = get_user(value, (uint32_t *)buf); 304 - if (r) 287 + if (r) { 288 + pm_runtime_mark_last_busy(adev->ddev->dev); 289 + pm_runtime_put_autosuspend(adev->ddev->dev); 305 290 return r; 291 + } 306 292 307 293 WREG32_PCIE(*pos >> 2, value); 308 294 ··· 318 290 *pos += 4; 319 291 size -= 4; 320 292 } 293 + 294 + pm_runtime_mark_last_busy(adev->ddev->dev); 295 + pm_runtime_put_autosuspend(adev->ddev->dev); 321 296 322 297 return result; 323 298 } ··· 347 316 if (size & 0x3 || *pos & 0x3) 348 317 return -EINVAL; 349 318 319 + r = pm_runtime_get_sync(adev->ddev->dev); 320 + if (r < 0) 321 + return r; 322 + 350 323 while (size) { 351 324 uint32_t value; 352 325 353 326 value = RREG32_DIDT(*pos >> 2); 354 327 r = put_user(value, (uint32_t *)buf); 355 - if (r) 328 + if (r) { 329 + pm_runtime_mark_last_busy(adev->ddev->dev); 330 + pm_runtime_put_autosuspend(adev->ddev->dev); 356 331 return r; 332 + } 357 333 358 334 result += 4; 359 335 buf += 4; 360 336 *pos += 4; 361 337 size -= 4; 362 338 } 339 + 340 + pm_runtime_mark_last_busy(adev->ddev->dev); 341 + pm_runtime_put_autosuspend(adev->ddev->dev); 363 342 364 343 return result; 365 344 } ··· 396 355 if (size & 0x3 || *pos & 0x3) 397 356 return -EINVAL; 398 357 358 + r = pm_runtime_get_sync(adev->ddev->dev); 359 + if (r < 0) 360 + return r; 361 + 399 362 while (size) { 400 363 uint32_t value; 401 364 402 365 r = get_user(value, (uint32_t *)buf); 403 - if (r) 366 + if (r) { 367 + pm_runtime_mark_last_busy(adev->ddev->dev); 368 + pm_runtime_put_autosuspend(adev->ddev->dev); 404 369 return r; 370 + } 405 371 406 372 WREG32_DIDT(*pos >> 2, value); 407 373 ··· 417 369 *pos += 4; 418 370 size -= 4; 419 371 } 372 + 373 + pm_runtime_mark_last_busy(adev->ddev->dev); 374 + pm_runtime_put_autosuspend(adev->ddev->dev); 420 375 421 376 return result; 422 377 } ··· 446 395 if (size & 0x3 || *pos & 0x3) 447 396 return -EINVAL; 448 397 398 + r = pm_runtime_get_sync(adev->ddev->dev); 399 + if (r < 0) 400 + return r; 401 + 449 402 while (size) { 450 403 uint32_t value; 451 404 452 405 value = RREG32_SMC(*pos); 453 406 r = put_user(value, (uint32_t *)buf); 454 - if (r) 407 + if (r) { 408 + pm_runtime_mark_last_busy(adev->ddev->dev); 409 + pm_runtime_put_autosuspend(adev->ddev->dev); 455 410 return r; 411 + } 456 412 457 413 result += 4; 458 414 buf += 4; 459 415 *pos += 4; 460 416 size -= 4; 461 417 } 418 + 419 + pm_runtime_mark_last_busy(adev->ddev->dev); 420 + pm_runtime_put_autosuspend(adev->ddev->dev); 462 421 463 422 return result; 464 423 } ··· 495 434 if (size & 0x3 || *pos & 0x3) 496 435 return -EINVAL; 497 436 437 + r = pm_runtime_get_sync(adev->ddev->dev); 438 + if (r < 0) 439 + return r; 440 + 498 441 while (size) { 499 442 uint32_t value; 500 443 501 444 r = get_user(value, (uint32_t *)buf); 502 - if (r) 445 + if (r) { 446 + pm_runtime_mark_last_busy(adev->ddev->dev); 447 + pm_runtime_put_autosuspend(adev->ddev->dev); 503 448 return r; 449 + } 504 450 505 451 WREG32_SMC(*pos, value); 506 452 ··· 516 448 *pos += 4; 517 449 size -= 4; 518 450 } 451 + 452 + pm_runtime_mark_last_busy(adev->ddev->dev); 453 + pm_runtime_put_autosuspend(adev->ddev->dev); 519 454 520 455 return result; 521 456 } ··· 643 572 idx = *pos >> 2; 644 573 645 574 valuesize = sizeof(values); 575 + 576 + r = pm_runtime_get_sync(adev->ddev->dev); 577 + if (r < 0) 578 + return r; 579 + 646 580 r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize); 581 + 582 + pm_runtime_mark_last_busy(adev->ddev->dev); 583 + pm_runtime_put_autosuspend(adev->ddev->dev); 584 + 647 585 if (r) 648 586 return r; 649 587 ··· 713 633 wave = (*pos & GENMASK_ULL(36, 31)) >> 31; 714 634 simd = (*pos & GENMASK_ULL(44, 37)) >> 37; 715 635 636 + r = pm_runtime_get_sync(adev->ddev->dev); 637 + if (r < 0) 638 + return r; 639 + 716 640 /* switch to the specific se/sh/cu */ 717 641 mutex_lock(&adev->grbm_idx_mutex); 718 642 amdgpu_gfx_select_se_sh(adev, se, sh, cu); ··· 727 643 728 644 amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); 729 645 mutex_unlock(&adev->grbm_idx_mutex); 646 + 647 + pm_runtime_mark_last_busy(adev->ddev->dev); 648 + pm_runtime_put_autosuspend(adev->ddev->dev); 730 649 731 650 if (!x) 732 651 return -EINVAL; ··· 798 711 if (!data) 799 712 return -ENOMEM; 800 713 714 + r = pm_runtime_get_sync(adev->ddev->dev); 715 + if (r < 0) 716 + return r; 717 + 801 718 /* switch to the specific se/sh/cu */ 802 719 mutex_lock(&adev->grbm_idx_mutex); 803 720 amdgpu_gfx_select_se_sh(adev, se, sh, cu); ··· 816 725 817 726 amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); 818 727 mutex_unlock(&adev->grbm_idx_mutex); 728 + 729 + pm_runtime_mark_last_busy(adev->ddev->dev); 730 + pm_runtime_put_autosuspend(adev->ddev->dev); 819 731 820 732 while (size) { 821 733 uint32_t value; ··· 953 859 struct amdgpu_device *adev = dev->dev_private; 954 860 int r = 0, i; 955 861 862 + r = pm_runtime_get_sync(dev->dev); 863 + if (r < 0) 864 + return r; 865 + 956 866 /* Avoid accidently unparking the sched thread during GPU reset */ 957 867 mutex_lock(&adev->lock_reset); 958 868 ··· 987 889 988 890 mutex_unlock(&adev->lock_reset); 989 891 892 + pm_runtime_mark_last_busy(dev->dev); 893 + pm_runtime_put_autosuspend(dev->dev); 894 + 990 895 return 0; 991 896 } 992 897 ··· 1008 907 struct drm_info_node *node = (struct drm_info_node *)m->private; 1009 908 struct drm_device *dev = node->minor->dev; 1010 909 struct amdgpu_device *adev = dev->dev_private; 910 + int r; 911 + 912 + r = pm_runtime_get_sync(dev->dev); 913 + if (r < 0) 914 + return r; 1011 915 1012 916 seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev)); 917 + 918 + pm_runtime_mark_last_busy(dev->dev); 919 + pm_runtime_put_autosuspend(dev->dev); 920 + 1013 921 return 0; 1014 922 } 1015 923 ··· 1027 917 struct drm_info_node *node = (struct drm_info_node *)m->private; 1028 918 struct drm_device *dev = node->minor->dev; 1029 919 struct amdgpu_device *adev = dev->dev_private; 920 + int r; 921 + 922 + r = pm_runtime_get_sync(dev->dev); 923 + if (r < 0) 924 + return r; 1030 925 1031 926 seq_printf(m, "(%d)\n", ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_TT)); 927 + 928 + pm_runtime_mark_last_busy(dev->dev); 929 + pm_runtime_put_autosuspend(dev->dev); 930 + 1032 931 return 0; 1033 932 } 1034 933
+8
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
··· 741 741 struct drm_info_node *node = (struct drm_info_node *) m->private; 742 742 struct drm_device *dev = node->minor->dev; 743 743 struct amdgpu_device *adev = dev->dev_private; 744 + int r; 745 + 746 + r = pm_runtime_get_sync(dev->dev); 747 + if (r < 0) 748 + return 0; 744 749 745 750 seq_printf(m, "gpu recover\n"); 746 751 amdgpu_device_gpu_recover(adev, NULL); 752 + 753 + pm_runtime_mark_last_busy(dev->dev); 754 + pm_runtime_put_autosuspend(dev->dev); 747 755 748 756 return 0; 749 757 }