diff options
-rw-r--r-- | drivers/thermal/int340x_thermal/int3400_thermal.c | 172 |
1 files changed, 13 insertions, 159 deletions
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index 9104b4f9381b..edc1cce117ba 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c | |||
@@ -14,33 +14,7 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
16 | #include <linux/thermal.h> | 16 | #include <linux/thermal.h> |
17 | 17 | #include "acpi_thermal_rel.h" | |
18 | struct art { | ||
19 | acpi_handle source; | ||
20 | acpi_handle target; | ||
21 | u64 weight; | ||
22 | u64 ac0_max; | ||
23 | u64 ac1_max; | ||
24 | u64 ac2_max; | ||
25 | u64 ac3_max; | ||
26 | u64 ac4_max; | ||
27 | u64 ac5_max; | ||
28 | u64 ac6_max; | ||
29 | u64 ac7_max; | ||
30 | u64 ac8_max; | ||
31 | u64 ac9_max; | ||
32 | }; | ||
33 | |||
34 | struct trt { | ||
35 | acpi_handle source; | ||
36 | acpi_handle target; | ||
37 | u64 influence; | ||
38 | u64 sampling_period; | ||
39 | u64 reverved1; | ||
40 | u64 reverved2; | ||
41 | u64 reverved3; | ||
42 | u64 reverved4; | ||
43 | }; | ||
44 | 18 | ||
45 | enum int3400_thermal_uuid { | 19 | enum int3400_thermal_uuid { |
46 | INT3400_THERMAL_PASSIVE_1, | 20 | INT3400_THERMAL_PASSIVE_1, |
@@ -68,6 +42,7 @@ struct int3400_thermal_priv { | |||
68 | int trt_count; | 42 | int trt_count; |
69 | struct trt *trts; | 43 | struct trt *trts; |
70 | u8 uuid_bitmap; | 44 | u8 uuid_bitmap; |
45 | int rel_misc_dev_res; | ||
71 | }; | 46 | }; |
72 | 47 | ||
73 | static int int3400_thermal_get_uuids(struct int3400_thermal_priv *priv) | 48 | static int int3400_thermal_get_uuids(struct int3400_thermal_priv *priv) |
@@ -146,136 +121,6 @@ static int int3400_thermal_run_osc(acpi_handle handle, | |||
146 | return result; | 121 | return result; |
147 | } | 122 | } |
148 | 123 | ||
149 | |||
150 | static int parse_art(struct int3400_thermal_priv *priv) | ||
151 | { | ||
152 | acpi_handle handle = priv->adev->handle; | ||
153 | acpi_status status; | ||
154 | int result = 0; | ||
155 | int i; | ||
156 | struct acpi_device *adev; | ||
157 | union acpi_object *p; | ||
158 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
159 | struct acpi_buffer element = { 0, NULL }; | ||
160 | struct acpi_buffer art_format = { | ||
161 | sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" }; | ||
162 | |||
163 | if (!acpi_has_method(handle, "_ART")) | ||
164 | return 0; | ||
165 | |||
166 | status = acpi_evaluate_object(handle, "_ART", NULL, &buffer); | ||
167 | if (ACPI_FAILURE(status)) | ||
168 | return -ENODEV; | ||
169 | |||
170 | p = buffer.pointer; | ||
171 | if (!p || (p->type != ACPI_TYPE_PACKAGE)) { | ||
172 | pr_err("Invalid _ART data\n"); | ||
173 | result = -EFAULT; | ||
174 | goto end; | ||
175 | } | ||
176 | |||
177 | /* ignore p->package.elements[0], as this is _ART Revision field */ | ||
178 | priv->art_count = p->package.count - 1; | ||
179 | priv->arts = kzalloc(sizeof(struct art) * priv->art_count, GFP_KERNEL); | ||
180 | if (!priv->arts) { | ||
181 | result = -ENOMEM; | ||
182 | goto end; | ||
183 | } | ||
184 | |||
185 | for (i = 0; i < priv->art_count; i++) { | ||
186 | struct art *art = &(priv->arts[i]); | ||
187 | |||
188 | element.length = sizeof(struct art); | ||
189 | element.pointer = art; | ||
190 | |||
191 | status = acpi_extract_package(&(p->package.elements[i + 1]), | ||
192 | &art_format, &element); | ||
193 | if (ACPI_FAILURE(status)) { | ||
194 | pr_err("Invalid _ART data"); | ||
195 | result = -EFAULT; | ||
196 | kfree(priv->arts); | ||
197 | goto end; | ||
198 | } | ||
199 | result = acpi_bus_get_device(art->source, &adev); | ||
200 | if (!result) | ||
201 | acpi_create_platform_device(adev, NULL); | ||
202 | else | ||
203 | pr_warn("Failed to get source ACPI device\n"); | ||
204 | result = acpi_bus_get_device(art->target, &adev); | ||
205 | if (!result) | ||
206 | acpi_create_platform_device(adev, NULL); | ||
207 | else | ||
208 | pr_warn("Failed to get source ACPI device\n"); | ||
209 | } | ||
210 | end: | ||
211 | kfree(buffer.pointer); | ||
212 | return result; | ||
213 | } | ||
214 | |||
215 | static int parse_trt(struct int3400_thermal_priv *priv) | ||
216 | { | ||
217 | acpi_handle handle = priv->adev->handle; | ||
218 | acpi_status status; | ||
219 | int result = 0; | ||
220 | int i; | ||
221 | struct acpi_device *adev; | ||
222 | union acpi_object *p; | ||
223 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
224 | struct acpi_buffer element = { 0, NULL }; | ||
225 | struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" }; | ||
226 | |||
227 | if (!acpi_has_method(handle, "_TRT")) | ||
228 | return 0; | ||
229 | |||
230 | status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer); | ||
231 | if (ACPI_FAILURE(status)) | ||
232 | return -ENODEV; | ||
233 | |||
234 | p = buffer.pointer; | ||
235 | if (!p || (p->type != ACPI_TYPE_PACKAGE)) { | ||
236 | pr_err("Invalid _TRT data\n"); | ||
237 | result = -EFAULT; | ||
238 | goto end; | ||
239 | } | ||
240 | |||
241 | priv->trt_count = p->package.count; | ||
242 | priv->trts = kzalloc(sizeof(struct trt) * priv->trt_count, GFP_KERNEL); | ||
243 | if (!priv->trts) { | ||
244 | result = -ENOMEM; | ||
245 | goto end; | ||
246 | } | ||
247 | |||
248 | for (i = 0; i < priv->trt_count; i++) { | ||
249 | struct trt *trt = &(priv->trts[i]); | ||
250 | |||
251 | element.length = sizeof(struct trt); | ||
252 | element.pointer = trt; | ||
253 | |||
254 | status = acpi_extract_package(&(p->package.elements[i]), | ||
255 | &trt_format, &element); | ||
256 | if (ACPI_FAILURE(status)) { | ||
257 | pr_err("Invalid _ART data"); | ||
258 | result = -EFAULT; | ||
259 | kfree(priv->trts); | ||
260 | goto end; | ||
261 | } | ||
262 | |||
263 | result = acpi_bus_get_device(trt->source, &adev); | ||
264 | if (!result) | ||
265 | acpi_create_platform_device(adev, NULL); | ||
266 | else | ||
267 | pr_warn("Failed to get source ACPI device\n"); | ||
268 | result = acpi_bus_get_device(trt->target, &adev); | ||
269 | if (!result) | ||
270 | acpi_create_platform_device(adev, NULL); | ||
271 | else | ||
272 | pr_warn("Failed to get target ACPI device\n"); | ||
273 | } | ||
274 | end: | ||
275 | kfree(buffer.pointer); | ||
276 | return result; | ||
277 | } | ||
278 | |||
279 | static int int3400_thermal_get_temp(struct thermal_zone_device *thermal, | 124 | static int int3400_thermal_get_temp(struct thermal_zone_device *thermal, |
280 | unsigned long *temp) | 125 | unsigned long *temp) |
281 | { | 126 | { |
@@ -350,11 +195,14 @@ static int int3400_thermal_probe(struct platform_device *pdev) | |||
350 | if (result) | 195 | if (result) |
351 | goto free_priv; | 196 | goto free_priv; |
352 | 197 | ||
353 | result = parse_art(priv); | 198 | result = acpi_parse_art(priv->adev->handle, &priv->art_count, |
199 | &priv->arts, true); | ||
354 | if (result) | 200 | if (result) |
355 | goto free_priv; | 201 | goto free_priv; |
356 | 202 | ||
357 | result = parse_trt(priv); | 203 | |
204 | result = acpi_parse_trt(priv->adev->handle, &priv->trt_count, | ||
205 | &priv->trts, true); | ||
358 | if (result) | 206 | if (result) |
359 | goto free_art; | 207 | goto free_art; |
360 | 208 | ||
@@ -372,6 +220,9 @@ static int int3400_thermal_probe(struct platform_device *pdev) | |||
372 | goto free_trt; | 220 | goto free_trt; |
373 | } | 221 | } |
374 | 222 | ||
223 | priv->rel_misc_dev_res = acpi_thermal_rel_misc_device_add( | ||
224 | priv->adev->handle); | ||
225 | |||
375 | return 0; | 226 | return 0; |
376 | free_trt: | 227 | free_trt: |
377 | kfree(priv->trts); | 228 | kfree(priv->trts); |
@@ -386,6 +237,9 @@ static int int3400_thermal_remove(struct platform_device *pdev) | |||
386 | { | 237 | { |
387 | struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); | 238 | struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); |
388 | 239 | ||
240 | if (!priv->rel_misc_dev_res) | ||
241 | acpi_thermal_rel_misc_device_remove(priv->adev->handle); | ||
242 | |||
389 | thermal_zone_device_unregister(priv->thermal); | 243 | thermal_zone_device_unregister(priv->thermal); |
390 | kfree(priv->trts); | 244 | kfree(priv->trts); |
391 | kfree(priv->arts); | 245 | kfree(priv->arts); |