Commit 445e0bc7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hwmon-for-v6.0-rc5' of...

Merge tag 'hwmon-for-v6.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:

 - Fix severe regression in asus-ec-sensors driver
   which resulted in EC driver failures

 - Fix various bugs in mr75203 driver

 - Fix byte order bug in tps23861 driver

* tag 'hwmon-for-v6.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (asus-ec-sensors) autoload module via DMI data
  hwmon: (mr75203) enable polling for all VM channels
  hwmon: (mr75203) fix multi-channel voltage reading
  hwmon: (mr75203) fix voltage equation for negative source input
  hwmon: (mr75203) update pvt->v_num and vm_num to the actual number of used sensors
  hwmon: (mr75203) fix VM sensor allocation when "intel,vm-map" not defined
  dt-bindings: hwmon: (mr75203) fix "intel,vm-map" property to be optional
  hwmon: (tps23861) fix byte order in resistance register
parents 16547b21 88700d13
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ required:
  - compatible
  - reg
  - reg-names
  - intel,vm-map
  - clocks
  - resets
  - "#thermal-sensor-cells"
+222 −186
Original line number Diff line number Diff line
@@ -266,9 +266,7 @@ static const struct ec_sensor_info sensors_family_intel_600[] = {
#define SENSOR_SET_WATER_BLOCK                                                 \
	(SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT)


struct ec_board_info {
	const char *board_names[MAX_IDENTICAL_BOARD_VARIATIONS];
	unsigned long sensors;
	/*
	 * Defines which mutex to use for guarding access to the state and the
@@ -281,39 +279,38 @@ struct ec_board_info {
	enum board_family family;
};

static const struct ec_board_info board_info[] = {
	{
		.board_names = {"PRIME X470-PRO"},
static const struct ec_board_info board_info_prime_x470_pro = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
		SENSOR_FAN_CPU_OPT |
		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
	.mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
	.family = family_amd_400_series,
	},
	{
		.board_names = {"PRIME X570-PRO"},
};

static const struct ec_board_info board_info_prime_x570_pro = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ProArt X570-CREATOR WIFI"},
};

static const struct ec_board_info board_info_pro_art_x570_creator_wifi = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT |
		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
	},
	{
		.board_names = {"Pro WS X570-ACE"},
	.family = family_amd_500_series,
};

static const struct ec_board_info board_info_pro_ws_x570_ace = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET |
		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG CROSSHAIR VIII DARK HERO"},
};

static const struct ec_board_info board_info_crosshair_viii_dark_hero = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR |
		SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
@@ -321,13 +318,9 @@ static const struct ec_board_info board_info[] = {
		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {
			"ROG CROSSHAIR VIII FORMULA",
			"ROG CROSSHAIR VIII HERO",
			"ROG CROSSHAIR VIII HERO (WI-FI)",
		},
};

static const struct ec_board_info board_info_crosshair_viii_hero = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR |
		SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
@@ -336,86 +329,83 @@ static const struct ec_board_info board_info[] = {
		SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {
			"ROG MAXIMUS XI HERO",
			"ROG MAXIMUS XI HERO (WI-FI)",
		},
};

static const struct ec_board_info board_info_maximus_xi_hero = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR |
		SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
		SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_intel_300_series,
	},
	{
		.board_names = {"ROG CROSSHAIR VIII IMPACT"},
};

static const struct ec_board_info board_info_crosshair_viii_impact = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
		SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
		SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG STRIX B550-E GAMING"},
};

static const struct ec_board_info board_info_strix_b550_e_gaming = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
		SENSOR_FAN_CPU_OPT,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG STRIX B550-I GAMING"},
};

static const struct ec_board_info board_info_strix_b550_i_gaming = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
		SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU |
		SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG STRIX X570-E GAMING"},
};

static const struct ec_board_info board_info_strix_x570_e_gaming = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
		SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
		SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG STRIX X570-E GAMING WIFI II"},
};

static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU |
		SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG STRIX X570-F GAMING"},
};

static const struct ec_board_info board_info_strix_x570_f_gaming = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG STRIX X570-I GAMING"},
};

static const struct ec_board_info board_info_strix_x570_i_gaming = {
	.sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM |
		SENSOR_TEMP_T_SENSOR |
		SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET |
		SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
	.family = family_amd_500_series,
	},
	{
		.board_names = {"ROG STRIX Z690-A GAMING WIFI D4"},
};

static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 = {
	.sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX,
	.family = family_intel_600_series,
	},
	{
		.board_names = {"ROG ZENITH II EXTREME"},
};

static const struct ec_board_info board_info_zenith_ii_extreme = {
	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
		SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
		SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS |
@@ -425,8 +415,58 @@ static const struct ec_board_info board_info[] = {
		SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3,
	.mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0,
	.family = family_amd_500_series,
	},
	{}
};

#define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info)                      \
	{                                                                      \
		.matches = {                                                   \
			DMI_EXACT_MATCH(DMI_BOARD_VENDOR,                      \
					"ASUSTeK COMPUTER INC."),              \
			DMI_EXACT_MATCH(DMI_BOARD_NAME, name),                 \
		},                                                             \
		.driver_data = (void *)board_info,                              \
	}

static const struct dmi_system_id dmi_table[] = {
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO",
					&board_info_prime_x470_pro),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO",
					&board_info_prime_x570_pro),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI",
					&board_info_pro_art_x570_creator_wifi),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE",
					&board_info_pro_ws_x570_ace),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO",
					&board_info_crosshair_viii_dark_hero),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA",
					&board_info_crosshair_viii_hero),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO",
					&board_info_crosshair_viii_hero),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO (WI-FI)",
					&board_info_crosshair_viii_hero),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO",
					&board_info_maximus_xi_hero),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO (WI-FI)",
					&board_info_maximus_xi_hero),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT",
					&board_info_crosshair_viii_impact),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING",
					&board_info_strix_b550_e_gaming),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING",
					&board_info_strix_b550_i_gaming),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING",
					&board_info_strix_x570_e_gaming),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING WIFI II",
					&board_info_strix_x570_e_gaming_wifi_ii),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING",
					&board_info_strix_x570_f_gaming),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-I GAMING",
					&board_info_strix_x570_i_gaming),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4",
					&board_info_strix_z690_a_gaming_wifi_d4),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME",
					&board_info_zenith_ii_extreme),
	{},
};

struct ec_sensor {
@@ -537,12 +577,12 @@ static int find_ec_sensor_index(const struct ec_sensors_data *ec,
	return -ENOENT;
}

static int __init bank_compare(const void *a, const void *b)
static int bank_compare(const void *a, const void *b)
{
	return *((const s8 *)a) - *((const s8 *)b);
}

static void __init setup_sensor_data(struct ec_sensors_data *ec)
static void setup_sensor_data(struct ec_sensors_data *ec)
{
	struct ec_sensor *s = ec->sensors;
	bool bank_found;
@@ -574,7 +614,7 @@ static void __init setup_sensor_data(struct ec_sensors_data *ec)
	sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL);
}

static void __init fill_ec_registers(struct ec_sensors_data *ec)
static void fill_ec_registers(struct ec_sensors_data *ec)
{
	const struct ec_sensor_info *si;
	unsigned int i, j, register_idx = 0;
@@ -589,7 +629,7 @@ static void __init fill_ec_registers(struct ec_sensors_data *ec)
	}
}

static int __init setup_lock_data(struct device *dev)
static int setup_lock_data(struct device *dev)
{
	const char *mutex_path;
	int status;
@@ -812,7 +852,7 @@ static umode_t asus_ec_hwmon_is_visible(const void *drvdata,
	return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0;
}

static int __init
static int
asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan,
			     struct device *dev, int num,
			     enum hwmon_sensor_types type, u32 config)
@@ -841,27 +881,15 @@ static struct hwmon_chip_info asus_ec_chip_info = {
	.ops = &asus_ec_hwmon_ops,
};

static const struct ec_board_info * __init get_board_info(void)
static const struct ec_board_info *get_board_info(void)
{
	const char *dmi_board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
	const char *dmi_board_name = dmi_get_system_info(DMI_BOARD_NAME);
	const struct ec_board_info *board;

	if (!dmi_board_vendor || !dmi_board_name ||
	    strcasecmp(dmi_board_vendor, "ASUSTeK COMPUTER INC."))
		return NULL;
	const struct dmi_system_id *dmi_entry;

	for (board = board_info; board->sensors; board++) {
		if (match_string(board->board_names,
				 MAX_IDENTICAL_BOARD_VARIATIONS,
				 dmi_board_name) >= 0)
			return board;
	dmi_entry = dmi_first_match(dmi_table);
	return dmi_entry ? dmi_entry->driver_data : NULL;
}

	return NULL;
}

static int __init asus_ec_probe(struct platform_device *pdev)
static int asus_ec_probe(struct platform_device *pdev)
{
	const struct hwmon_channel_info **ptr_asus_ec_ci;
	int nr_count[hwmon_max] = { 0 }, nr_types = 0;
@@ -970,29 +998,37 @@ static int __init asus_ec_probe(struct platform_device *pdev)
	return PTR_ERR_OR_ZERO(hwdev);
}


static const struct acpi_device_id acpi_ec_ids[] = {
	/* Embedded Controller Device */
	{ "PNP0C09", 0 },
	{}
};
MODULE_DEVICE_TABLE(dmi, dmi_table);

static struct platform_driver asus_ec_sensors_platform_driver = {
	.driver = {
		.name	= "asus-ec-sensors",
		.acpi_match_table = acpi_ec_ids,
	},
	.probe = asus_ec_probe,
};

MODULE_DEVICE_TABLE(acpi, acpi_ec_ids);
/*
 * we use module_platform_driver_probe() rather than module_platform_driver()
 * because the probe function (and its dependants) are marked with __init, which
 * means we can't put it into the .probe member of the platform_driver struct
 * above, and we can't mark the asus_ec_sensors_platform_driver object as __init
 * because the object is referenced from the module exit code.
 */
module_platform_driver_probe(asus_ec_sensors_platform_driver, asus_ec_probe);
static struct platform_device *asus_ec_sensors_platform_device;

static int __init asus_ec_init(void)
{
	asus_ec_sensors_platform_device =
		platform_create_bundle(&asus_ec_sensors_platform_driver,
				       asus_ec_probe, NULL, 0, NULL, 0);

	if (IS_ERR(asus_ec_sensors_platform_device))
		return PTR_ERR(asus_ec_sensors_platform_device);

	return 0;
}

static void __exit asus_ec_exit(void)
{
	platform_device_unregister(asus_ec_sensors_platform_device);
	platform_driver_unregister(&asus_ec_sensors_platform_driver);
}

module_init(asus_ec_init);
module_exit(asus_ec_exit);

module_param_named(mutex_path, mutex_path_override, charp, 0);
MODULE_PARM_DESC(mutex_path,
+50 −22
Original line number Diff line number Diff line
@@ -68,8 +68,9 @@

/* VM Individual Macro Register */
#define VM_COM_REG_SIZE	0x200
#define VM_SDIF_DONE(n)	(VM_COM_REG_SIZE + 0x34 + 0x200 * (n))
#define VM_SDIF_DATA(n)	(VM_COM_REG_SIZE + 0x40 + 0x200 * (n))
#define VM_SDIF_DONE(vm)	(VM_COM_REG_SIZE + 0x34 + 0x200 * (vm))
#define VM_SDIF_DATA(vm, ch)	\
	(VM_COM_REG_SIZE + 0x40 + 0x200 * (vm) + 0x4 * (ch))

/* SDA Slave Register */
#define IP_CTRL			0x00
@@ -115,6 +116,7 @@ struct pvt_device {
	u32			t_num;
	u32			p_num;
	u32			v_num;
	u32			c_num;
	u32			ip_freq;
	u8			*vm_idx;
};
@@ -178,14 +180,15 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
{
	struct pvt_device *pvt = dev_get_drvdata(dev);
	struct regmap *v_map = pvt->v_map;
	u8 vm_idx, ch_idx;
	u32 n, stat;
	u8 vm_idx;
	int ret;

	if (channel >= pvt->v_num)
	if (channel >= pvt->v_num * pvt->c_num)
		return -EINVAL;

	vm_idx = pvt->vm_idx[channel];
	vm_idx = pvt->vm_idx[channel / pvt->c_num];
	ch_idx = channel % pvt->c_num;

	switch (attr) {
	case hwmon_in_input:
@@ -196,13 +199,23 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
		if (ret)
			return ret;

		ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx), &n);
		ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx, ch_idx), &n);
		if(ret < 0)
			return ret;

		n &= SAMPLE_DATA_MSK;
		/* Convert the N bitstream count into voltage */
		*val = (PVT_N_CONST * n - PVT_R_CONST) >> PVT_CONV_BITS;
		/*
		 * Convert the N bitstream count into voltage.
		 * To support negative voltage calculation for 64bit machines
		 * n must be cast to long, since n and *val differ both in
		 * signedness and in size.
		 * Division is used instead of right shift, because for signed
		 * numbers, the sign bit is used to fill the vacated bit
		 * positions, and if the number is negative, 1 is used.
		 * BIT(x) may not be used instead of (1 << x) because it's
		 * unsigned.
		 */
		*val = (PVT_N_CONST * (long)n - PVT_R_CONST) / (1 << PVT_CONV_BITS);

		return 0;
	default:
@@ -375,6 +388,19 @@ static int pvt_init(struct pvt_device *pvt)
		if (ret)
			return ret;

		val = (BIT(pvt->c_num) - 1) | VM_CH_INIT |
		      IP_POLL << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(v_map, SDIF_W, val);
		if (ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT |
		      CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT |
		      SDIF_WRN_W | SDIF_PROG;
@@ -489,8 +515,8 @@ static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt

static int mr75203_probe(struct platform_device *pdev)
{
	u32 ts_num, vm_num, pd_num, ch_num, val, index, i;
	const struct hwmon_channel_info **pvt_info;
	u32 ts_num, vm_num, pd_num, val, index, i;
	struct device *dev = &pdev->dev;
	u32 *temp_config, *in_config;
	struct device *hwmon_dev;
@@ -531,9 +557,11 @@ static int mr75203_probe(struct platform_device *pdev)
	ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
	pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
	vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
	ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT;
	pvt->t_num = ts_num;
	pvt->p_num = pd_num;
	pvt->v_num = vm_num;
	pvt->c_num = ch_num;
	val = 0;
	if (ts_num)
		val++;
@@ -570,7 +598,7 @@ static int mr75203_probe(struct platform_device *pdev)
	}

	if (vm_num) {
		u32 num = vm_num;
		u32 total_ch;

		ret = pvt_get_regmap(pdev, "vm", pvt);
		if (ret)
@@ -584,30 +612,30 @@ static int mr75203_probe(struct platform_device *pdev)
		ret = device_property_read_u8_array(dev, "intel,vm-map",
						    pvt->vm_idx, vm_num);
		if (ret) {
			num = 0;
			/*
			 * Incase intel,vm-map property is not defined, we
			 * assume incremental channel numbers.
			 */
			for (i = 0; i < vm_num; i++)
				pvt->vm_idx[i] = i;
		} else {
			for (i = 0; i < vm_num; i++)
				if (pvt->vm_idx[i] >= vm_num ||
				    pvt->vm_idx[i] == 0xff) {
					num = i;
					pvt->v_num = i;
					vm_num = i;
					break;
				}
		}

		/*
		 * Incase intel,vm-map property is not defined, we assume
		 * incremental channel numbers.
		 */
		for (i = num; i < vm_num; i++)
			pvt->vm_idx[i] = i;

		in_config = devm_kcalloc(dev, num + 1,
		total_ch = ch_num * vm_num;
		in_config = devm_kcalloc(dev, total_ch + 1,
					 sizeof(*in_config), GFP_KERNEL);
		if (!in_config)
			return -ENOMEM;

		memset32(in_config, HWMON_I_INPUT, num);
		in_config[num] = 0;
		memset32(in_config, HWMON_I_INPUT, total_ch);
		in_config[total_ch] = 0;
		pvt_in.config = in_config;

		pvt_info[index++] = &pvt_in;
+6 −4
Original line number Diff line number Diff line
@@ -493,18 +493,20 @@ static char *tps23861_port_poe_plus_status(struct tps23861_data *data, int port)

static int tps23861_port_resistance(struct tps23861_data *data, int port)
{
	u16 regval;
	unsigned int raw_val;
	__le16 regval;

	regmap_bulk_read(data->regmap,
			 PORT_1_RESISTANCE_LSB + PORT_N_RESISTANCE_LSB_OFFSET * (port - 1),
			 &regval,
			 2);

	switch (FIELD_GET(PORT_RESISTANCE_RSN_MASK, regval)) {
	raw_val = le16_to_cpu(regval);
	switch (FIELD_GET(PORT_RESISTANCE_RSN_MASK, raw_val)) {
	case PORT_RESISTANCE_RSN_OTHER:
		return (FIELD_GET(PORT_RESISTANCE_MASK, regval) * RESISTANCE_LSB) / 10000;
		return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB) / 10000;
	case PORT_RESISTANCE_RSN_LOW:
		return (FIELD_GET(PORT_RESISTANCE_MASK, regval) * RESISTANCE_LSB_LOW) / 10000;
		return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB_LOW) / 10000;
	case PORT_RESISTANCE_RSN_SHORT:
	case PORT_RESISTANCE_RSN_OPEN:
	default: