xref: /linux/drivers/accel/habanalabs/common/hwmon.c (revision 1f20a5769446a1acae67ac9e63d07a594829a789)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7 
8 #include "habanalabs.h"
9 
10 #include <linux/pci.h>
11 #include <linux/hwmon.h>
12 
13 #define HWMON_NR_SENSOR_TYPES		(hwmon_max)
14 
15 #ifdef _HAS_HWMON_HWMON_T_ENABLE
16 
17 static u32 fixup_flags_legacy_fw(struct hl_device *hdev, enum hwmon_sensor_types type,
18 					u32 cpucp_flags)
19 {
20 	u32 flags;
21 
22 	switch (type) {
23 	case hwmon_temp:
24 		flags = (cpucp_flags << 1) | HWMON_T_ENABLE;
25 		break;
26 
27 	case hwmon_in:
28 		flags = (cpucp_flags << 1) | HWMON_I_ENABLE;
29 		break;
30 
31 	case hwmon_curr:
32 		flags = (cpucp_flags << 1) | HWMON_C_ENABLE;
33 		break;
34 
35 	case hwmon_fan:
36 		flags = (cpucp_flags << 1) | HWMON_F_ENABLE;
37 		break;
38 
39 	case hwmon_power:
40 		flags = (cpucp_flags << 1) | HWMON_P_ENABLE;
41 		break;
42 
43 	case hwmon_pwm:
44 		/* enable bit was here from day 1, so no need to adjust */
45 		flags = cpucp_flags;
46 		break;
47 
48 	default:
49 		dev_err_ratelimited(hdev->dev, "unsupported h/w sensor type %d\n", type);
50 		flags = cpucp_flags;
51 		break;
52 	}
53 
54 	return flags;
55 }
56 
57 static u32 fixup_attr_legacy_fw(u32 attr)
58 {
59 	return (attr - 1);
60 }
61 
62 #else
63 
64 static u32 fixup_flags_legacy_fw(struct hl_device *hdev, enum hwmon_sensor_types type,
65 						u32 cpucp_flags)
66 {
67 	return cpucp_flags;
68 }
69 
70 static u32 fixup_attr_legacy_fw(u32 attr)
71 {
72 	return attr;
73 }
74 
75 #endif /* !_HAS_HWMON_HWMON_T_ENABLE */
76 
77 static u32 adjust_hwmon_flags(struct hl_device *hdev, enum hwmon_sensor_types type, u32 cpucp_flags)
78 {
79 	u32 flags, cpucp_input_val;
80 	bool use_cpucp_enum;
81 
82 	use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
83 					CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;
84 
85 	/* If f/w is using it's own enum, we need to check if the properties values are aligned.
86 	 * If not, it means we need to adjust the values to the new format that is used in the
87 	 * kernel since 5.6 (enum values were incremented by 1 by adding a new enable value).
88 	 */
89 	if (use_cpucp_enum) {
90 		switch (type) {
91 		case hwmon_temp:
92 			cpucp_input_val = cpucp_temp_input;
93 			if (cpucp_input_val == hwmon_temp_input)
94 				flags = cpucp_flags;
95 			else
96 				flags = (cpucp_flags << 1) | HWMON_T_ENABLE;
97 			break;
98 
99 		case hwmon_in:
100 			cpucp_input_val = cpucp_in_input;
101 			if (cpucp_input_val == hwmon_in_input)
102 				flags = cpucp_flags;
103 			else
104 				flags = (cpucp_flags << 1) | HWMON_I_ENABLE;
105 			break;
106 
107 		case hwmon_curr:
108 			cpucp_input_val = cpucp_curr_input;
109 			if (cpucp_input_val == hwmon_curr_input)
110 				flags = cpucp_flags;
111 			else
112 				flags = (cpucp_flags << 1) | HWMON_C_ENABLE;
113 			break;
114 
115 		case hwmon_fan:
116 			cpucp_input_val = cpucp_fan_input;
117 			if (cpucp_input_val == hwmon_fan_input)
118 				flags = cpucp_flags;
119 			else
120 				flags = (cpucp_flags << 1) | HWMON_F_ENABLE;
121 			break;
122 
123 		case hwmon_pwm:
124 			/* enable bit was here from day 1, so no need to adjust */
125 			flags = cpucp_flags;
126 			break;
127 
128 		case hwmon_power:
129 			cpucp_input_val = CPUCP_POWER_INPUT;
130 			if (cpucp_input_val == hwmon_power_input)
131 				flags = cpucp_flags;
132 			else
133 				flags = (cpucp_flags << 1) | HWMON_P_ENABLE;
134 			break;
135 
136 		default:
137 			dev_err_ratelimited(hdev->dev, "unsupported h/w sensor type %d\n", type);
138 			flags = cpucp_flags;
139 			break;
140 		}
141 	} else {
142 		flags = fixup_flags_legacy_fw(hdev, type, cpucp_flags);
143 	}
144 
145 	return flags;
146 }
147 
148 int hl_build_hwmon_channel_info(struct hl_device *hdev, struct cpucp_sensor *sensors_arr)
149 {
150 	u32 num_sensors_for_type, flags, num_active_sensor_types = 0, arr_size = 0, *curr_arr;
151 	u32 sensors_by_type_next_index[HWMON_NR_SENSOR_TYPES] = {0};
152 	u32 *sensors_by_type[HWMON_NR_SENSOR_TYPES] = {NULL};
153 	struct hwmon_channel_info **channels_info;
154 	u32 counts[HWMON_NR_SENSOR_TYPES] = {0};
155 	enum hwmon_sensor_types type;
156 	int rc, i, j;
157 
158 	for (i = 0 ; i < CPUCP_MAX_SENSORS ; i++) {
159 		type = le32_to_cpu(sensors_arr[i].type);
160 
161 		if ((type == 0) && (sensors_arr[i].flags == 0))
162 			break;
163 
164 		if (type >= HWMON_NR_SENSOR_TYPES) {
165 			dev_err_ratelimited(hdev->dev,
166 				"Got wrong sensor type %d from device\n", type);
167 			return -EINVAL;
168 		}
169 
170 		counts[type]++;
171 		arr_size++;
172 	}
173 
174 	for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
175 		if (counts[i] == 0)
176 			continue;
177 
178 		num_sensors_for_type = counts[i] + 1;
179 		dev_dbg(hdev->dev, "num_sensors_for_type %d = %d\n", i, num_sensors_for_type);
180 
181 		curr_arr = kcalloc(num_sensors_for_type, sizeof(*curr_arr), GFP_KERNEL);
182 		if (!curr_arr) {
183 			rc = -ENOMEM;
184 			goto sensors_type_err;
185 		}
186 
187 		num_active_sensor_types++;
188 		sensors_by_type[i] = curr_arr;
189 	}
190 
191 	for (i = 0 ; i < arr_size ; i++) {
192 		type = le32_to_cpu(sensors_arr[i].type);
193 		curr_arr = sensors_by_type[type];
194 		flags = adjust_hwmon_flags(hdev, type, le32_to_cpu(sensors_arr[i].flags));
195 		curr_arr[sensors_by_type_next_index[type]++] = flags;
196 	}
197 
198 	channels_info = kcalloc(num_active_sensor_types + 1, sizeof(struct hwmon_channel_info *),
199 				GFP_KERNEL);
200 	if (!channels_info) {
201 		rc = -ENOMEM;
202 		goto channels_info_array_err;
203 	}
204 
205 	for (i = 0 ; i < num_active_sensor_types ; i++) {
206 		channels_info[i] = kzalloc(sizeof(*channels_info[i]), GFP_KERNEL);
207 		if (!channels_info[i]) {
208 			rc = -ENOMEM;
209 			goto channel_info_err;
210 		}
211 	}
212 
213 	for (i = 0, j = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
214 		if (!sensors_by_type[i])
215 			continue;
216 
217 		channels_info[j]->type = i;
218 		channels_info[j]->config = sensors_by_type[i];
219 		j++;
220 	}
221 
222 	hdev->hl_chip_info->info = (const struct hwmon_channel_info **)channels_info;
223 
224 	return 0;
225 
226 channel_info_err:
227 	for (i = 0 ; i < num_active_sensor_types ; i++) {
228 		if (channels_info[i]) {
229 			kfree(channels_info[i]->config);
230 			kfree(channels_info[i]);
231 		}
232 	}
233 	kfree(channels_info);
234 
235 channels_info_array_err:
236 sensors_type_err:
237 	for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++)
238 		kfree(sensors_by_type[i]);
239 
240 	return rc;
241 }
242 
243 static int hl_read(struct device *dev, enum hwmon_sensor_types type,
244 			u32 attr, int channel, long *val)
245 {
246 	struct hl_device *hdev = dev_get_drvdata(dev);
247 	bool use_cpucp_enum;
248 	u32 cpucp_attr;
249 	int rc;
250 
251 	if (!hl_device_operational(hdev, NULL))
252 		return -ENODEV;
253 
254 	use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
255 					CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;
256 
257 	switch (type) {
258 	case hwmon_temp:
259 		switch (attr) {
260 		case hwmon_temp_input:
261 			cpucp_attr = cpucp_temp_input;
262 			break;
263 		case hwmon_temp_max:
264 			cpucp_attr = cpucp_temp_max;
265 			break;
266 		case hwmon_temp_crit:
267 			cpucp_attr = cpucp_temp_crit;
268 			break;
269 		case hwmon_temp_max_hyst:
270 			cpucp_attr = cpucp_temp_max_hyst;
271 			break;
272 		case hwmon_temp_crit_hyst:
273 			cpucp_attr = cpucp_temp_crit_hyst;
274 			break;
275 		case hwmon_temp_offset:
276 			cpucp_attr = cpucp_temp_offset;
277 			break;
278 		case hwmon_temp_highest:
279 			cpucp_attr = cpucp_temp_highest;
280 			break;
281 		default:
282 			return -EINVAL;
283 		}
284 
285 		if (use_cpucp_enum)
286 			rc = hl_get_temperature(hdev, channel, cpucp_attr, val);
287 		else
288 			rc = hl_get_temperature(hdev, channel, fixup_attr_legacy_fw(attr), val);
289 		break;
290 	case hwmon_in:
291 		switch (attr) {
292 		case hwmon_in_input:
293 			cpucp_attr = cpucp_in_input;
294 			break;
295 		case hwmon_in_min:
296 			cpucp_attr = cpucp_in_min;
297 			break;
298 		case hwmon_in_max:
299 			cpucp_attr = cpucp_in_max;
300 			break;
301 		case hwmon_in_highest:
302 			cpucp_attr = cpucp_in_highest;
303 			break;
304 		default:
305 			return -EINVAL;
306 		}
307 
308 		if (use_cpucp_enum)
309 			rc = hl_get_voltage(hdev, channel, cpucp_attr, val);
310 		else
311 			rc = hl_get_voltage(hdev, channel, fixup_attr_legacy_fw(attr), val);
312 		break;
313 	case hwmon_curr:
314 		switch (attr) {
315 		case hwmon_curr_input:
316 			cpucp_attr = cpucp_curr_input;
317 			break;
318 		case hwmon_curr_min:
319 			cpucp_attr = cpucp_curr_min;
320 			break;
321 		case hwmon_curr_max:
322 			cpucp_attr = cpucp_curr_max;
323 			break;
324 		case hwmon_curr_highest:
325 			cpucp_attr = cpucp_curr_highest;
326 			break;
327 		default:
328 			return -EINVAL;
329 		}
330 
331 		if (use_cpucp_enum)
332 			rc = hl_get_current(hdev, channel, cpucp_attr, val);
333 		else
334 			rc = hl_get_current(hdev, channel, fixup_attr_legacy_fw(attr), val);
335 		break;
336 	case hwmon_fan:
337 		switch (attr) {
338 		case hwmon_fan_input:
339 			cpucp_attr = cpucp_fan_input;
340 			break;
341 		case hwmon_fan_min:
342 			cpucp_attr = cpucp_fan_min;
343 			break;
344 		case hwmon_fan_max:
345 			cpucp_attr = cpucp_fan_max;
346 			break;
347 		default:
348 			return -EINVAL;
349 		}
350 
351 		if (use_cpucp_enum)
352 			rc = hl_get_fan_speed(hdev, channel, cpucp_attr, val);
353 		else
354 			rc = hl_get_fan_speed(hdev, channel, fixup_attr_legacy_fw(attr), val);
355 		break;
356 	case hwmon_pwm:
357 		switch (attr) {
358 		case hwmon_pwm_input:
359 			cpucp_attr = cpucp_pwm_input;
360 			break;
361 		case hwmon_pwm_enable:
362 			cpucp_attr = cpucp_pwm_enable;
363 			break;
364 		default:
365 			return -EINVAL;
366 		}
367 
368 		if (use_cpucp_enum)
369 			rc = hl_get_pwm_info(hdev, channel, cpucp_attr, val);
370 		else
371 			/* no need for fixup as pwm was aligned from day 1 */
372 			rc = hl_get_pwm_info(hdev, channel, attr, val);
373 		break;
374 	case hwmon_power:
375 		switch (attr) {
376 		case hwmon_power_input:
377 			cpucp_attr = CPUCP_POWER_INPUT;
378 			break;
379 		case hwmon_power_input_highest:
380 			cpucp_attr = CPUCP_POWER_INPUT_HIGHEST;
381 			break;
382 		default:
383 			return -EINVAL;
384 		}
385 
386 		if (use_cpucp_enum)
387 			rc = hl_get_power(hdev, channel, cpucp_attr, val);
388 		else
389 			rc = hl_get_power(hdev, channel, fixup_attr_legacy_fw(attr), val);
390 		break;
391 	default:
392 		return -EINVAL;
393 	}
394 	return rc;
395 }
396 
397 static int hl_write(struct device *dev, enum hwmon_sensor_types type,
398 			u32 attr, int channel, long val)
399 {
400 	struct hl_device *hdev = dev_get_drvdata(dev);
401 	u32 cpucp_attr;
402 	bool use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
403 				CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;
404 
405 	if (!hl_device_operational(hdev, NULL))
406 		return -ENODEV;
407 
408 	switch (type) {
409 	case hwmon_temp:
410 		switch (attr) {
411 		case hwmon_temp_offset:
412 			cpucp_attr = cpucp_temp_offset;
413 			break;
414 		case hwmon_temp_reset_history:
415 			cpucp_attr = cpucp_temp_reset_history;
416 			break;
417 		default:
418 			return -EINVAL;
419 		}
420 
421 		if (use_cpucp_enum)
422 			hl_set_temperature(hdev, channel, cpucp_attr, val);
423 		else
424 			hl_set_temperature(hdev, channel, fixup_attr_legacy_fw(attr), val);
425 		break;
426 	case hwmon_pwm:
427 		switch (attr) {
428 		case hwmon_pwm_input:
429 			cpucp_attr = cpucp_pwm_input;
430 			break;
431 		case hwmon_pwm_enable:
432 			cpucp_attr = cpucp_pwm_enable;
433 			break;
434 		default:
435 			return -EINVAL;
436 		}
437 
438 		if (use_cpucp_enum)
439 			hl_set_pwm_info(hdev, channel, cpucp_attr, val);
440 		else
441 			/* no need for fixup as pwm was aligned from day 1 */
442 			hl_set_pwm_info(hdev, channel, attr, val);
443 		break;
444 	case hwmon_in:
445 		switch (attr) {
446 		case hwmon_in_reset_history:
447 			cpucp_attr = cpucp_in_reset_history;
448 			break;
449 		default:
450 			return -EINVAL;
451 		}
452 
453 		if (use_cpucp_enum)
454 			hl_set_voltage(hdev, channel, cpucp_attr, val);
455 		else
456 			hl_set_voltage(hdev, channel, fixup_attr_legacy_fw(attr), val);
457 		break;
458 	case hwmon_curr:
459 		switch (attr) {
460 		case hwmon_curr_reset_history:
461 			cpucp_attr = cpucp_curr_reset_history;
462 			break;
463 		default:
464 			return -EINVAL;
465 		}
466 
467 		if (use_cpucp_enum)
468 			hl_set_current(hdev, channel, cpucp_attr, val);
469 		else
470 			hl_set_current(hdev, channel, fixup_attr_legacy_fw(attr), val);
471 		break;
472 	case hwmon_power:
473 		switch (attr) {
474 		case hwmon_power_reset_history:
475 			cpucp_attr = CPUCP_POWER_RESET_INPUT_HISTORY;
476 			break;
477 		default:
478 			return -EINVAL;
479 		}
480 
481 		if (use_cpucp_enum)
482 			hl_set_power(hdev, channel, cpucp_attr, val);
483 		else
484 			hl_set_power(hdev, channel, fixup_attr_legacy_fw(attr), val);
485 		break;
486 	default:
487 		return -EINVAL;
488 	}
489 	return 0;
490 }
491 
492 static umode_t hl_is_visible(const void *data, enum hwmon_sensor_types type,
493 				u32 attr, int channel)
494 {
495 	switch (type) {
496 	case hwmon_temp:
497 		switch (attr) {
498 		case hwmon_temp_input:
499 		case hwmon_temp_max:
500 		case hwmon_temp_max_hyst:
501 		case hwmon_temp_crit:
502 		case hwmon_temp_crit_hyst:
503 		case hwmon_temp_highest:
504 			return 0444;
505 		case hwmon_temp_offset:
506 			return 0644;
507 		case hwmon_temp_reset_history:
508 			return 0200;
509 		}
510 		break;
511 	case hwmon_in:
512 		switch (attr) {
513 		case hwmon_in_input:
514 		case hwmon_in_min:
515 		case hwmon_in_max:
516 		case hwmon_in_highest:
517 			return 0444;
518 		case hwmon_in_reset_history:
519 			return 0200;
520 		}
521 		break;
522 	case hwmon_curr:
523 		switch (attr) {
524 		case hwmon_curr_input:
525 		case hwmon_curr_min:
526 		case hwmon_curr_max:
527 		case hwmon_curr_highest:
528 			return 0444;
529 		case hwmon_curr_reset_history:
530 			return 0200;
531 		}
532 		break;
533 	case hwmon_fan:
534 		switch (attr) {
535 		case hwmon_fan_input:
536 		case hwmon_fan_min:
537 		case hwmon_fan_max:
538 			return 0444;
539 		}
540 		break;
541 	case hwmon_pwm:
542 		switch (attr) {
543 		case hwmon_pwm_input:
544 		case hwmon_pwm_enable:
545 			return 0644;
546 		}
547 		break;
548 	case hwmon_power:
549 		switch (attr) {
550 		case hwmon_power_input:
551 		case hwmon_power_input_highest:
552 			return 0444;
553 		case hwmon_power_reset_history:
554 			return 0200;
555 		}
556 		break;
557 	default:
558 		break;
559 	}
560 	return 0;
561 }
562 
563 static const struct hwmon_ops hl_hwmon_ops = {
564 	.is_visible = hl_is_visible,
565 	.read = hl_read,
566 	.write = hl_write
567 };
568 
569 int hl_get_temperature(struct hl_device *hdev,
570 			int sensor_index, u32 attr, long *value)
571 {
572 	struct cpucp_packet pkt;
573 	u64 result;
574 	int rc;
575 
576 	memset(&pkt, 0, sizeof(pkt));
577 
578 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_GET <<
579 				CPUCP_PKT_CTL_OPCODE_SHIFT);
580 	pkt.sensor_index = __cpu_to_le16(sensor_index);
581 	pkt.type = __cpu_to_le16(attr);
582 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
583 						0, &result);
584 
585 	*value = (long) result;
586 
587 	if (rc) {
588 		dev_err_ratelimited(hdev->dev,
589 			"Failed to get temperature from sensor %d, error %d\n",
590 			sensor_index, rc);
591 		*value = 0;
592 	}
593 
594 	return rc;
595 }
596 
597 int hl_set_temperature(struct hl_device *hdev,
598 			int sensor_index, u32 attr, long value)
599 {
600 	struct cpucp_packet pkt;
601 	int rc;
602 
603 	memset(&pkt, 0, sizeof(pkt));
604 
605 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_SET <<
606 				CPUCP_PKT_CTL_OPCODE_SHIFT);
607 	pkt.sensor_index = __cpu_to_le16(sensor_index);
608 	pkt.type = __cpu_to_le16(attr);
609 	pkt.value = __cpu_to_le64(value);
610 
611 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
612 						0, NULL);
613 
614 	if (rc)
615 		dev_err_ratelimited(hdev->dev,
616 			"Failed to set temperature of sensor %d, error %d\n",
617 			sensor_index, rc);
618 
619 	return rc;
620 }
621 
622 int hl_get_voltage(struct hl_device *hdev,
623 			int sensor_index, u32 attr, long *value)
624 {
625 	struct cpucp_packet pkt;
626 	u64 result;
627 	int rc;
628 
629 	memset(&pkt, 0, sizeof(pkt));
630 
631 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_GET <<
632 				CPUCP_PKT_CTL_OPCODE_SHIFT);
633 	pkt.sensor_index = __cpu_to_le16(sensor_index);
634 	pkt.type = __cpu_to_le16(attr);
635 
636 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
637 						0, &result);
638 
639 	*value = (long) result;
640 
641 	if (rc) {
642 		dev_err_ratelimited(hdev->dev,
643 			"Failed to get voltage from sensor %d, error %d\n",
644 			sensor_index, rc);
645 		*value = 0;
646 	}
647 
648 	return rc;
649 }
650 
651 int hl_get_current(struct hl_device *hdev,
652 			int sensor_index, u32 attr, long *value)
653 {
654 	struct cpucp_packet pkt;
655 	u64 result;
656 	int rc;
657 
658 	memset(&pkt, 0, sizeof(pkt));
659 
660 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_GET <<
661 				CPUCP_PKT_CTL_OPCODE_SHIFT);
662 	pkt.sensor_index = __cpu_to_le16(sensor_index);
663 	pkt.type = __cpu_to_le16(attr);
664 
665 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
666 						0, &result);
667 
668 	*value = (long) result;
669 
670 	if (rc) {
671 		dev_err_ratelimited(hdev->dev,
672 			"Failed to get current from sensor %d, error %d\n",
673 			sensor_index, rc);
674 		*value = 0;
675 	}
676 
677 	return rc;
678 }
679 
680 int hl_get_fan_speed(struct hl_device *hdev,
681 			int sensor_index, u32 attr, long *value)
682 {
683 	struct cpucp_packet pkt;
684 	u64 result;
685 	int rc;
686 
687 	memset(&pkt, 0, sizeof(pkt));
688 
689 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_FAN_SPEED_GET <<
690 				CPUCP_PKT_CTL_OPCODE_SHIFT);
691 	pkt.sensor_index = __cpu_to_le16(sensor_index);
692 	pkt.type = __cpu_to_le16(attr);
693 
694 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
695 						0, &result);
696 
697 	*value = (long) result;
698 
699 	if (rc) {
700 		dev_err_ratelimited(hdev->dev,
701 			"Failed to get fan speed from sensor %d, error %d\n",
702 			sensor_index, rc);
703 		*value = 0;
704 	}
705 
706 	return rc;
707 }
708 
709 int hl_get_pwm_info(struct hl_device *hdev,
710 			int sensor_index, u32 attr, long *value)
711 {
712 	struct cpucp_packet pkt;
713 	u64 result;
714 	int rc;
715 
716 	memset(&pkt, 0, sizeof(pkt));
717 
718 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_GET <<
719 				CPUCP_PKT_CTL_OPCODE_SHIFT);
720 	pkt.sensor_index = __cpu_to_le16(sensor_index);
721 	pkt.type = __cpu_to_le16(attr);
722 
723 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
724 						0, &result);
725 
726 	*value = (long) result;
727 
728 	if (rc) {
729 		dev_err_ratelimited(hdev->dev,
730 			"Failed to get pwm info from sensor %d, error %d\n",
731 			sensor_index, rc);
732 		*value = 0;
733 	}
734 
735 	return rc;
736 }
737 
738 void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
739 			long value)
740 {
741 	struct cpucp_packet pkt;
742 	int rc;
743 
744 	memset(&pkt, 0, sizeof(pkt));
745 
746 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_SET <<
747 				CPUCP_PKT_CTL_OPCODE_SHIFT);
748 	pkt.sensor_index = __cpu_to_le16(sensor_index);
749 	pkt.type = __cpu_to_le16(attr);
750 	pkt.value = cpu_to_le64(value);
751 
752 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
753 						0, NULL);
754 
755 	if (rc)
756 		dev_err_ratelimited(hdev->dev,
757 			"Failed to set pwm info to sensor %d, error %d\n",
758 			sensor_index, rc);
759 }
760 
761 int hl_set_voltage(struct hl_device *hdev,
762 			int sensor_index, u32 attr, long value)
763 {
764 	struct cpucp_packet pkt;
765 	int rc;
766 
767 	memset(&pkt, 0, sizeof(pkt));
768 
769 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_SET <<
770 				CPUCP_PKT_CTL_OPCODE_SHIFT);
771 	pkt.sensor_index = __cpu_to_le16(sensor_index);
772 	pkt.type = __cpu_to_le16(attr);
773 	pkt.value = __cpu_to_le64(value);
774 
775 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
776 						0, NULL);
777 
778 	if (rc)
779 		dev_err_ratelimited(hdev->dev,
780 			"Failed to set voltage of sensor %d, error %d\n",
781 			sensor_index, rc);
782 
783 	return rc;
784 }
785 
786 int hl_set_current(struct hl_device *hdev,
787 			int sensor_index, u32 attr, long value)
788 {
789 	struct cpucp_packet pkt;
790 	int rc;
791 
792 	memset(&pkt, 0, sizeof(pkt));
793 
794 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_SET <<
795 				CPUCP_PKT_CTL_OPCODE_SHIFT);
796 	pkt.sensor_index = __cpu_to_le16(sensor_index);
797 	pkt.type = __cpu_to_le16(attr);
798 	pkt.value = __cpu_to_le64(value);
799 
800 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
801 						0, NULL);
802 
803 	if (rc)
804 		dev_err_ratelimited(hdev->dev,
805 			"Failed to set current of sensor %d, error %d\n",
806 			sensor_index, rc);
807 
808 	return rc;
809 }
810 
811 int hl_set_power(struct hl_device *hdev,
812 			int sensor_index, u32 attr, long value)
813 {
814 	struct cpucp_packet pkt;
815 	struct asic_fixed_properties *prop = &hdev->asic_prop;
816 	int rc;
817 
818 	memset(&pkt, 0, sizeof(pkt));
819 
820 	if (prop->use_get_power_for_reset_history)
821 		pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
822 				CPUCP_PKT_CTL_OPCODE_SHIFT);
823 	else
824 		pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_SET <<
825 				CPUCP_PKT_CTL_OPCODE_SHIFT);
826 
827 	pkt.sensor_index = __cpu_to_le16(sensor_index);
828 	pkt.type = __cpu_to_le16(attr);
829 	pkt.value = __cpu_to_le64(value);
830 
831 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
832 						0, NULL);
833 
834 	if (rc)
835 		dev_err_ratelimited(hdev->dev,
836 			"Failed to set power of sensor %d, error %d\n",
837 			sensor_index, rc);
838 
839 	return rc;
840 }
841 
842 int hl_get_power(struct hl_device *hdev,
843 			int sensor_index, u32 attr, long *value)
844 {
845 	struct cpucp_packet pkt;
846 	u64 result;
847 	int rc;
848 
849 	memset(&pkt, 0, sizeof(pkt));
850 
851 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
852 				CPUCP_PKT_CTL_OPCODE_SHIFT);
853 	pkt.sensor_index = __cpu_to_le16(sensor_index);
854 	pkt.type = __cpu_to_le16(attr);
855 
856 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
857 						0, &result);
858 
859 	*value = (long) result;
860 
861 	if (rc) {
862 		dev_err_ratelimited(hdev->dev,
863 			"Failed to get power of sensor %d, error %d\n",
864 			sensor_index, rc);
865 		*value = 0;
866 	}
867 
868 	return rc;
869 }
870 
871 int hl_hwmon_init(struct hl_device *hdev)
872 {
873 	struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev;
874 	struct asic_fixed_properties *prop = &hdev->asic_prop;
875 	int rc;
876 
877 	if ((hdev->hwmon_initialized) || !(hdev->cpu_queues_enable))
878 		return 0;
879 
880 	if (hdev->hl_chip_info->info) {
881 		hdev->hl_chip_info->ops = &hl_hwmon_ops;
882 
883 		hdev->hwmon_dev = hwmon_device_register_with_info(dev,
884 					prop->cpucp_info.card_name, hdev,
885 					hdev->hl_chip_info, NULL);
886 		if (IS_ERR(hdev->hwmon_dev)) {
887 			rc = PTR_ERR(hdev->hwmon_dev);
888 			dev_err(hdev->dev,
889 				"Unable to register hwmon device: %d\n", rc);
890 			return rc;
891 		}
892 
893 		dev_info(hdev->dev, "%s: add sensors information\n",
894 			dev_name(hdev->hwmon_dev));
895 
896 		hdev->hwmon_initialized = true;
897 	} else {
898 		dev_info(hdev->dev, "no available sensors\n");
899 	}
900 
901 	return 0;
902 }
903 
904 void hl_hwmon_fini(struct hl_device *hdev)
905 {
906 	if (!hdev->hwmon_initialized)
907 		return;
908 
909 	hwmon_device_unregister(hdev->hwmon_dev);
910 }
911 
912 void hl_hwmon_release_resources(struct hl_device *hdev)
913 {
914 	const struct hwmon_channel_info * const *channel_info_arr;
915 	int i = 0;
916 
917 	if (!hdev->hl_chip_info->info)
918 		return;
919 
920 	channel_info_arr = hdev->hl_chip_info->info;
921 
922 	while (channel_info_arr[i]) {
923 		kfree(channel_info_arr[i]->config);
924 		kfree(channel_info_arr[i]);
925 		i++;
926 	}
927 
928 	kfree(channel_info_arr);
929 
930 	hdev->hl_chip_info->info = NULL;
931 }
932