// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright 2016-2019 HabanaLabs, Ltd.
 * All Rights Reserved.
 */

#include "habanalabs.h"

#include <linux/pci.h>
#include <linux/hwmon.h>

#define HWMON_NR_SENSOR_TYPES		(hwmon_max)

#ifdef _HAS_HWMON_HWMON_T_ENABLE

static u32 fixup_flags_legacy_fw(struct hl_device *hdev, enum hwmon_sensor_types type,
					u32 cpucp_flags)
{
	u32 flags;

	switch (type) {
	case hwmon_temp:
		flags = (cpucp_flags << 1) | HWMON_T_ENABLE;
		break;

	case hwmon_in:
		flags = (cpucp_flags << 1) | HWMON_I_ENABLE;
		break;

	case hwmon_curr:
		flags = (cpucp_flags << 1) | HWMON_C_ENABLE;
		break;

	case hwmon_fan:
		flags = (cpucp_flags << 1) | HWMON_F_ENABLE;
		break;

	case hwmon_power:
		flags = (cpucp_flags << 1) | HWMON_P_ENABLE;
		break;

	case hwmon_pwm:
		/* enable bit was here from day 1, so no need to adjust */
		flags = cpucp_flags;
		break;

	default:
		dev_err_ratelimited(hdev->dev, "unsupported h/w sensor type %d\n", type);
		flags = cpucp_flags;
		break;
	}

	return flags;
}

static u32 fixup_attr_legacy_fw(u32 attr)
{
	return (attr - 1);
}

#else

static u32 fixup_flags_legacy_fw(struct hl_device *hdev, enum hwmon_sensor_types type,
						u32 cpucp_flags)
{
	return cpucp_flags;
}

static u32 fixup_attr_legacy_fw(u32 attr)
{
	return attr;
}

#endif /* !_HAS_HWMON_HWMON_T_ENABLE */

static u32 adjust_hwmon_flags(struct hl_device *hdev, enum hwmon_sensor_types type, u32 cpucp_flags)
{
	u32 flags, cpucp_input_val;
	bool use_cpucp_enum;

	use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
					CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;

	/* If f/w is using it's own enum, we need to check if the properties values are aligned.
	 * If not, it means we need to adjust the values to the new format that is used in the
	 * kernel since 5.6 (enum values were incremented by 1 by adding a new enable value).
	 */
	if (use_cpucp_enum) {
		switch (type) {
		case hwmon_temp:
			cpucp_input_val = cpucp_temp_input;
			if (cpucp_input_val == hwmon_temp_input)
				flags = cpucp_flags;
			else
				flags = (cpucp_flags << 1) | HWMON_T_ENABLE;
			break;

		case hwmon_in:
			cpucp_input_val = cpucp_in_input;
			if (cpucp_input_val == hwmon_in_input)
				flags = cpucp_flags;
			else
				flags = (cpucp_flags << 1) | HWMON_I_ENABLE;
			break;

		case hwmon_curr:
			cpucp_input_val = cpucp_curr_input;
			if (cpucp_input_val == hwmon_curr_input)
				flags = cpucp_flags;
			else
				flags = (cpucp_flags << 1) | HWMON_C_ENABLE;
			break;

		case hwmon_fan:
			cpucp_input_val = cpucp_fan_input;
			if (cpucp_input_val == hwmon_fan_input)
				flags = cpucp_flags;
			else
				flags = (cpucp_flags << 1) | HWMON_F_ENABLE;
			break;

		case hwmon_pwm:
			/* enable bit was here from day 1, so no need to adjust */
			flags = cpucp_flags;
			break;

		case hwmon_power:
			cpucp_input_val = CPUCP_POWER_INPUT;
			if (cpucp_input_val == hwmon_power_input)
				flags = cpucp_flags;
			else
				flags = (cpucp_flags << 1) | HWMON_P_ENABLE;
			break;

		default:
			dev_err_ratelimited(hdev->dev, "unsupported h/w sensor type %d\n", type);
			flags = cpucp_flags;
			break;
		}
	} else {
		flags = fixup_flags_legacy_fw(hdev, type, cpucp_flags);
	}

	return flags;
}

int hl_build_hwmon_channel_info(struct hl_device *hdev, struct cpucp_sensor *sensors_arr)
{
	u32 num_sensors_for_type, flags, num_active_sensor_types = 0, arr_size = 0, *curr_arr;
	u32 sensors_by_type_next_index[HWMON_NR_SENSOR_TYPES] = {0};
	u32 *sensors_by_type[HWMON_NR_SENSOR_TYPES] = {NULL};
	struct hwmon_channel_info **channels_info;
	u32 counts[HWMON_NR_SENSOR_TYPES] = {0};
	enum hwmon_sensor_types type;
	int rc, i, j;

	for (i = 0 ; i < CPUCP_MAX_SENSORS ; i++) {
		type = le32_to_cpu(sensors_arr[i].type);

		if ((type == 0) && (sensors_arr[i].flags == 0))
			break;

		if (type >= HWMON_NR_SENSOR_TYPES) {
			dev_err_ratelimited(hdev->dev,
				"Got wrong sensor type %d from device\n", type);
			return -EINVAL;
		}

		counts[type]++;
		arr_size++;
	}

	for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
		if (counts[i] == 0)
			continue;

		num_sensors_for_type = counts[i] + 1;
		dev_dbg(hdev->dev, "num_sensors_for_type %d = %d\n", i, num_sensors_for_type);

		curr_arr = kcalloc(num_sensors_for_type, sizeof(*curr_arr), GFP_KERNEL);
		if (!curr_arr) {
			rc = -ENOMEM;
			goto sensors_type_err;
		}

		num_active_sensor_types++;
		sensors_by_type[i] = curr_arr;
	}

	for (i = 0 ; i < arr_size ; i++) {
		type = le32_to_cpu(sensors_arr[i].type);
		curr_arr = sensors_by_type[type];
		flags = adjust_hwmon_flags(hdev, type, le32_to_cpu(sensors_arr[i].flags));
		curr_arr[sensors_by_type_next_index[type]++] = flags;
	}

	channels_info = kcalloc(num_active_sensor_types + 1, sizeof(struct hwmon_channel_info *),
				GFP_KERNEL);
	if (!channels_info) {
		rc = -ENOMEM;
		goto channels_info_array_err;
	}

	for (i = 0 ; i < num_active_sensor_types ; i++) {
		channels_info[i] = kzalloc(sizeof(*channels_info[i]), GFP_KERNEL);
		if (!channels_info[i]) {
			rc = -ENOMEM;
			goto channel_info_err;
		}
	}

	for (i = 0, j = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
		if (!sensors_by_type[i])
			continue;

		channels_info[j]->type = i;
		channels_info[j]->config = sensors_by_type[i];
		j++;
	}

	hdev->hl_chip_info->info = (const struct hwmon_channel_info **)channels_info;

	return 0;

channel_info_err:
	for (i = 0 ; i < num_active_sensor_types ; i++) {
		if (channels_info[i]) {
			kfree(channels_info[i]->config);
			kfree(channels_info[i]);
		}
	}
	kfree(channels_info);

channels_info_array_err:
sensors_type_err:
	for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++)
		kfree(sensors_by_type[i]);

	return rc;
}

static int hl_read(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long *val)
{
	struct hl_device *hdev = dev_get_drvdata(dev);
	bool use_cpucp_enum;
	u32 cpucp_attr;
	int rc;

	if (!hl_device_operational(hdev, NULL))
		return -ENODEV;

	use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
					CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;

	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
			cpucp_attr = cpucp_temp_input;
			break;
		case hwmon_temp_max:
			cpucp_attr = cpucp_temp_max;
			break;
		case hwmon_temp_crit:
			cpucp_attr = cpucp_temp_crit;
			break;
		case hwmon_temp_max_hyst:
			cpucp_attr = cpucp_temp_max_hyst;
			break;
		case hwmon_temp_crit_hyst:
			cpucp_attr = cpucp_temp_crit_hyst;
			break;
		case hwmon_temp_offset:
			cpucp_attr = cpucp_temp_offset;
			break;
		case hwmon_temp_highest:
			cpucp_attr = cpucp_temp_highest;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			rc = hl_get_temperature(hdev, channel, cpucp_attr, val);
		else
			rc = hl_get_temperature(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	case hwmon_in:
		switch (attr) {
		case hwmon_in_input:
			cpucp_attr = cpucp_in_input;
			break;
		case hwmon_in_min:
			cpucp_attr = cpucp_in_min;
			break;
		case hwmon_in_max:
			cpucp_attr = cpucp_in_max;
			break;
		case hwmon_in_highest:
			cpucp_attr = cpucp_in_highest;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			rc = hl_get_voltage(hdev, channel, cpucp_attr, val);
		else
			rc = hl_get_voltage(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	case hwmon_curr:
		switch (attr) {
		case hwmon_curr_input:
			cpucp_attr = cpucp_curr_input;
			break;
		case hwmon_curr_min:
			cpucp_attr = cpucp_curr_min;
			break;
		case hwmon_curr_max:
			cpucp_attr = cpucp_curr_max;
			break;
		case hwmon_curr_highest:
			cpucp_attr = cpucp_curr_highest;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			rc = hl_get_current(hdev, channel, cpucp_attr, val);
		else
			rc = hl_get_current(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_input:
			cpucp_attr = cpucp_fan_input;
			break;
		case hwmon_fan_min:
			cpucp_attr = cpucp_fan_min;
			break;
		case hwmon_fan_max:
			cpucp_attr = cpucp_fan_max;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			rc = hl_get_fan_speed(hdev, channel, cpucp_attr, val);
		else
			rc = hl_get_fan_speed(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_input:
			cpucp_attr = cpucp_pwm_input;
			break;
		case hwmon_pwm_enable:
			cpucp_attr = cpucp_pwm_enable;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			rc = hl_get_pwm_info(hdev, channel, cpucp_attr, val);
		else
			/* no need for fixup as pwm was aligned from day 1 */
			rc = hl_get_pwm_info(hdev, channel, attr, val);
		break;
	case hwmon_power:
		switch (attr) {
		case hwmon_power_input:
			cpucp_attr = CPUCP_POWER_INPUT;
			break;
		case hwmon_power_input_highest:
			cpucp_attr = CPUCP_POWER_INPUT_HIGHEST;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			rc = hl_get_power(hdev, channel, cpucp_attr, val);
		else
			rc = hl_get_power(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	default:
		return -EINVAL;
	}
	return rc;
}

static int hl_write(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long val)
{
	struct hl_device *hdev = dev_get_drvdata(dev);
	u32 cpucp_attr;
	bool use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
				CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;

	if (!hl_device_operational(hdev, NULL))
		return -ENODEV;

	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_offset:
			cpucp_attr = cpucp_temp_offset;
			break;
		case hwmon_temp_reset_history:
			cpucp_attr = cpucp_temp_reset_history;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			hl_set_temperature(hdev, channel, cpucp_attr, val);
		else
			hl_set_temperature(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_input:
			cpucp_attr = cpucp_pwm_input;
			break;
		case hwmon_pwm_enable:
			cpucp_attr = cpucp_pwm_enable;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			hl_set_pwm_info(hdev, channel, cpucp_attr, val);
		else
			/* no need for fixup as pwm was aligned from day 1 */
			hl_set_pwm_info(hdev, channel, attr, val);
		break;
	case hwmon_in:
		switch (attr) {
		case hwmon_in_reset_history:
			cpucp_attr = cpucp_in_reset_history;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			hl_set_voltage(hdev, channel, cpucp_attr, val);
		else
			hl_set_voltage(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	case hwmon_curr:
		switch (attr) {
		case hwmon_curr_reset_history:
			cpucp_attr = cpucp_curr_reset_history;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			hl_set_current(hdev, channel, cpucp_attr, val);
		else
			hl_set_current(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	case hwmon_power:
		switch (attr) {
		case hwmon_power_reset_history:
			cpucp_attr = CPUCP_POWER_RESET_INPUT_HISTORY;
			break;
		default:
			return -EINVAL;
		}

		if (use_cpucp_enum)
			hl_set_power(hdev, channel, cpucp_attr, val);
		else
			hl_set_power(hdev, channel, fixup_attr_legacy_fw(attr), val);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static umode_t hl_is_visible(const void *data, enum hwmon_sensor_types type,
				u32 attr, int channel)
{
	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
		case hwmon_temp_max:
		case hwmon_temp_max_hyst:
		case hwmon_temp_crit:
		case hwmon_temp_crit_hyst:
		case hwmon_temp_highest:
			return 0444;
		case hwmon_temp_offset:
			return 0644;
		case hwmon_temp_reset_history:
			return 0200;
		}
		break;
	case hwmon_in:
		switch (attr) {
		case hwmon_in_input:
		case hwmon_in_min:
		case hwmon_in_max:
		case hwmon_in_highest:
			return 0444;
		case hwmon_in_reset_history:
			return 0200;
		}
		break;
	case hwmon_curr:
		switch (attr) {
		case hwmon_curr_input:
		case hwmon_curr_min:
		case hwmon_curr_max:
		case hwmon_curr_highest:
			return 0444;
		case hwmon_curr_reset_history:
			return 0200;
		}
		break;
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_input:
		case hwmon_fan_min:
		case hwmon_fan_max:
			return 0444;
		}
		break;
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_input:
		case hwmon_pwm_enable:
			return 0644;
		}
		break;
	case hwmon_power:
		switch (attr) {
		case hwmon_power_input:
		case hwmon_power_input_highest:
			return 0444;
		case hwmon_power_reset_history:
			return 0200;
		}
		break;
	default:
		break;
	}
	return 0;
}

static const struct hwmon_ops hl_hwmon_ops = {
	.is_visible = hl_is_visible,
	.read = hl_read,
	.write = hl_write
};

int hl_get_temperature(struct hl_device *hdev,
			int sensor_index, u32 attr, long *value)
{
	struct cpucp_packet pkt;
	u64 result;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_GET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);
	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, &result);

	*value = (long) result;

	if (rc) {
		if (rc != -EAGAIN)
			dev_err_ratelimited(hdev->dev,
				"Failed to get temperature from sensor %d, error %d\n",
				sensor_index, rc);
		*value = 0;
	}

	return rc;
}

int hl_set_temperature(struct hl_device *hdev,
			int sensor_index, u32 attr, long value)
{
	struct cpucp_packet pkt;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_SET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);
	pkt.value = __cpu_to_le64(value);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, NULL);
	if (rc && rc != -EAGAIN)
		dev_err_ratelimited(hdev->dev,
			"Failed to set temperature of sensor %d, error %d\n",
			sensor_index, rc);

	return rc;
}

int hl_get_voltage(struct hl_device *hdev,
			int sensor_index, u32 attr, long *value)
{
	struct cpucp_packet pkt;
	u64 result;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_GET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, &result);

	*value = (long) result;

	if (rc) {
		if (rc != -EAGAIN)
			dev_err_ratelimited(hdev->dev,
				"Failed to get voltage from sensor %d, error %d\n",
				sensor_index, rc);
		*value = 0;
	}

	return rc;
}

int hl_get_current(struct hl_device *hdev,
			int sensor_index, u32 attr, long *value)
{
	struct cpucp_packet pkt;
	u64 result;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_GET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, &result);

	*value = (long) result;

	if (rc) {
		if (rc != -EAGAIN)
			dev_err_ratelimited(hdev->dev,
				"Failed to get current from sensor %d, error %d\n",
				sensor_index, rc);
		*value = 0;
	}

	return rc;
}

int hl_get_fan_speed(struct hl_device *hdev,
			int sensor_index, u32 attr, long *value)
{
	struct cpucp_packet pkt;
	u64 result;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_FAN_SPEED_GET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, &result);

	*value = (long) result;

	if (rc) {
		if (rc != -EAGAIN)
			dev_err_ratelimited(hdev->dev,
				"Failed to get fan speed from sensor %d, error %d\n",
				sensor_index, rc);
		*value = 0;
	}

	return rc;
}

int hl_get_pwm_info(struct hl_device *hdev,
			int sensor_index, u32 attr, long *value)
{
	struct cpucp_packet pkt;
	u64 result;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_GET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, &result);

	*value = (long) result;

	if (rc) {
		if (rc != -EAGAIN)
			dev_err_ratelimited(hdev->dev,
				"Failed to get pwm info from sensor %d, error %d\n",
				sensor_index, rc);
		*value = 0;
	}

	return rc;
}

void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
			long value)
{
	struct cpucp_packet pkt;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_SET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);
	pkt.value = cpu_to_le64(value);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, NULL);
	if (rc && rc != -EAGAIN)
		dev_err_ratelimited(hdev->dev,
			"Failed to set pwm info to sensor %d, error %d\n",
			sensor_index, rc);
}

int hl_set_voltage(struct hl_device *hdev,
			int sensor_index, u32 attr, long value)
{
	struct cpucp_packet pkt;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_SET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);
	pkt.value = __cpu_to_le64(value);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, NULL);
	if (rc && rc != -EAGAIN)
		dev_err_ratelimited(hdev->dev,
			"Failed to set voltage of sensor %d, error %d\n",
			sensor_index, rc);

	return rc;
}

int hl_set_current(struct hl_device *hdev,
			int sensor_index, u32 attr, long value)
{
	struct cpucp_packet pkt;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_SET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);
	pkt.value = __cpu_to_le64(value);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, NULL);
	if (rc && rc != -EAGAIN)
		dev_err_ratelimited(hdev->dev,
			"Failed to set current of sensor %d, error %d\n",
			sensor_index, rc);

	return rc;
}

int hl_set_power(struct hl_device *hdev,
			int sensor_index, u32 attr, long value)
{
	struct cpucp_packet pkt;
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	if (prop->use_get_power_for_reset_history)
		pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	else
		pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_SET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);

	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);
	pkt.value = __cpu_to_le64(value);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, NULL);
	if (rc && rc != -EAGAIN)
		dev_err_ratelimited(hdev->dev,
			"Failed to set power of sensor %d, error %d\n",
			sensor_index, rc);

	return rc;
}

int hl_get_power(struct hl_device *hdev,
			int sensor_index, u32 attr, long *value)
{
	struct cpucp_packet pkt;
	u64 result;
	int rc;

	memset(&pkt, 0, sizeof(pkt));

	pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
				CPUCP_PKT_CTL_OPCODE_SHIFT);
	pkt.sensor_index = __cpu_to_le16(sensor_index);
	pkt.type = __cpu_to_le16(attr);

	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
						0, &result);

	*value = (long) result;

	if (rc) {
		if (rc != -EAGAIN)
			dev_err_ratelimited(hdev->dev,
				"Failed to get power of sensor %d, error %d\n",
				sensor_index, rc);
		*value = 0;
	}

	return rc;
}

int hl_hwmon_init(struct hl_device *hdev)
{
	struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev;
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	int rc;

	if ((hdev->hwmon_initialized) || !(hdev->cpu_queues_enable))
		return 0;

	if (hdev->hl_chip_info->info) {
		hdev->hl_chip_info->ops = &hl_hwmon_ops;

		hdev->hwmon_dev = hwmon_device_register_with_info(dev,
					prop->cpucp_info.card_name, hdev,
					hdev->hl_chip_info, NULL);
		if (IS_ERR(hdev->hwmon_dev)) {
			rc = PTR_ERR(hdev->hwmon_dev);
			dev_err(hdev->dev,
				"Unable to register hwmon device: %d\n", rc);
			return rc;
		}

		dev_info(hdev->dev, "%s: add sensors information\n",
			dev_name(hdev->hwmon_dev));

		hdev->hwmon_initialized = true;
	} else {
		dev_info(hdev->dev, "no available sensors\n");
	}

	return 0;
}

void hl_hwmon_fini(struct hl_device *hdev)
{
	if (!hdev->hwmon_initialized)
		return;

	hwmon_device_unregister(hdev->hwmon_dev);
}

void hl_hwmon_release_resources(struct hl_device *hdev)
{
	const struct hwmon_channel_info * const *channel_info_arr;
	int i = 0;

	if (!hdev->hl_chip_info->info)
		return;

	channel_info_arr = hdev->hl_chip_info->info;

	while (channel_info_arr[i]) {
		kfree(channel_info_arr[i]->config);
		kfree(channel_info_arr[i]);
		i++;
	}

	kfree(channel_info_arr);

	hdev->hl_chip_info->info = NULL;
}
