Commit | Line | Data |
---|---|---|
e071dce3 LL |
1 | /* |
2 | * Copyright 2021 Advanced Micro Devices, Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
20 | * OTHER DEALINGS IN THE SOFTWARE. | |
21 | * | |
22 | */ | |
23 | ||
24 | #include "amdgpu_reset.h" | |
25 | #include "aldebaran.h" | |
26 | ||
27 | int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl, | |
28 | struct amdgpu_reset_handler *handler) | |
29 | { | |
30 | /* TODO: Check if handler exists? */ | |
31 | list_add_tail(&handler->handler_list, &reset_ctl->reset_handlers); | |
32 | return 0; | |
33 | } | |
34 | ||
35 | int amdgpu_reset_init(struct amdgpu_device *adev) | |
36 | { | |
37 | int ret = 0; | |
38 | ||
142600e8 LL |
39 | switch (adev->asic_type) { |
40 | case CHIP_ALDEBARAN: | |
41 | ret = aldebaran_reset_init(adev); | |
42 | break; | |
43 | default: | |
44 | break; | |
45 | } | |
46 | ||
e071dce3 LL |
47 | return ret; |
48 | } | |
49 | ||
50 | int amdgpu_reset_fini(struct amdgpu_device *adev) | |
51 | { | |
52 | int ret = 0; | |
53 | ||
142600e8 LL |
54 | switch (adev->asic_type) { |
55 | case CHIP_ALDEBARAN: | |
56 | ret = aldebaran_reset_fini(adev); | |
57 | break; | |
58 | default: | |
59 | break; | |
60 | } | |
61 | ||
e071dce3 LL |
62 | return ret; |
63 | } | |
64 | ||
65 | int amdgpu_reset_prepare_hwcontext(struct amdgpu_device *adev, | |
66 | struct amdgpu_reset_context *reset_context) | |
67 | { | |
68 | struct amdgpu_reset_handler *reset_handler = NULL; | |
69 | ||
70 | if (adev->reset_cntl && adev->reset_cntl->get_reset_handler) | |
71 | reset_handler = adev->reset_cntl->get_reset_handler( | |
72 | adev->reset_cntl, reset_context); | |
73 | if (!reset_handler) | |
74 | return -ENOSYS; | |
75 | ||
76 | return reset_handler->prepare_hwcontext(adev->reset_cntl, | |
77 | reset_context); | |
78 | } | |
79 | ||
80 | int amdgpu_reset_perform_reset(struct amdgpu_device *adev, | |
81 | struct amdgpu_reset_context *reset_context) | |
82 | { | |
83 | int ret; | |
84 | struct amdgpu_reset_handler *reset_handler = NULL; | |
85 | ||
86 | if (adev->reset_cntl) | |
87 | reset_handler = adev->reset_cntl->get_reset_handler( | |
88 | adev->reset_cntl, reset_context); | |
89 | if (!reset_handler) | |
90 | return -ENOSYS; | |
91 | ||
92 | ret = reset_handler->perform_reset(adev->reset_cntl, reset_context); | |
93 | if (ret) | |
94 | return ret; | |
95 | ||
96 | return reset_handler->restore_hwcontext(adev->reset_cntl, | |
97 | reset_context); | |
98 | } | |
cfbb6b00 AG |
99 | |
100 | ||
101 | void amdgpu_reset_destroy_reset_domain(struct kref *ref) | |
102 | { | |
103 | struct amdgpu_reset_domain *reset_domain = container_of(ref, | |
104 | struct amdgpu_reset_domain, | |
105 | refcount); | |
106 | if (reset_domain->wq) | |
107 | destroy_workqueue(reset_domain->wq); | |
108 | ||
109 | kvfree(reset_domain); | |
110 | } | |
111 | ||
112 | struct amdgpu_reset_domain *amdgpu_reset_create_reset_domain(enum amdgpu_reset_domain_type type, | |
113 | char *wq_name) | |
114 | { | |
115 | struct amdgpu_reset_domain *reset_domain; | |
116 | ||
117 | reset_domain = kvzalloc(sizeof(struct amdgpu_reset_domain), GFP_KERNEL); | |
118 | if (!reset_domain) { | |
119 | DRM_ERROR("Failed to allocate amdgpu_reset_domain!"); | |
120 | return NULL; | |
121 | } | |
122 | ||
123 | reset_domain->type = type; | |
124 | kref_init(&reset_domain->refcount); | |
125 | ||
126 | reset_domain->wq = create_singlethread_workqueue(wq_name); | |
127 | if (!reset_domain->wq) { | |
128 | DRM_ERROR("Failed to allocate wq for amdgpu_reset_domain!"); | |
129 | amdgpu_reset_put_reset_domain(reset_domain); | |
130 | return NULL; | |
131 | ||
132 | } | |
133 | ||
134 | return reset_domain; | |
135 | } | |
136 | ||
137 | ||
138 |