All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] hwmon: (nct6775) Support access via Asus WMI
@ 2021-09-12 11:05 Denis Pauk
  2021-09-12 11:05 ` [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*() Denis Pauk
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Denis Pauk @ 2021-09-12 11:05 UTC (permalink / raw)
  Cc: pauk.denis, Bernhard Seibold, Pär Ekholm, to.eivind,
	Artem S . Tashkinov, Vittorio Roberto Alfieri, Sahan Fernando,
	Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-hwmon,
	linux-kernel

Support accessing the NCT677x via Asus WMI functions.

On mainboards that support this way of accessing the chip,
the driver will usually not work without this option since
in these mainboards, ACPI will mark the I/O port as used.

@Andy Shevchenko, I have left type of sioreg, in other places
sioreg has same integer type, should I change all occurrences
of usage?
@Guenter Roeck, I have left nct6775_*_set_back() call without
changes as its always called from platform specific callbacks.

Could you please review?

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Co-developed-by: Bernhard Seibold <mail@bernhard-seibold.de>
Signed-off-by: Bernhard Seibold <mail@bernhard-seibold.de>
Tested-by: Pär Ekholm <pehlm@pekholm.org>
Tested-by: <to.eivind@gmail.com>
Tested-by: Artem S. Tashkinov <aros@gmx.com>
Tested-by: Vittorio Roberto Alfieri <me@rebtoor.com>
Tested-by: Sahan Fernando <sahan.h.fernando@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>

---
Changes in v3:
  - Remove unrequired type conversions.
  - Make function declarations one line.
  - Use nct6775 function pointers in struct nct6775_data instead direct calls.

Changes in v2:
  - Split changes to separate patches.
  - Limit WMI usage by DMI_BOARD_NAME in checked ASUS motherboards.
  - Rearrange code for directly use struct nct6775_sio_data in superio_*()
    functions.


Denis Pauk (2):
  hwmon: (nct6775) Use sio_data in superio_*().
  hwmon: (nct6775) Support access via Asus WMI

 drivers/hwmon/nct6775.c | 687 ++++++++++++++++++++++++++--------------
 1 file changed, 450 insertions(+), 237 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*().
  2021-09-12 11:05 [PATCH v3 0/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
@ 2021-09-12 11:05 ` Denis Pauk
  2021-09-12 14:50     ` kernel test robot
  2021-09-12 11:05 ` [PATCH v3 2/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
  2021-09-12 15:14 ` [PATCH v3 0/2] " Andy Shevchenko
  2 siblings, 1 reply; 7+ messages in thread
From: Denis Pauk @ 2021-09-12 11:05 UTC (permalink / raw)
  Cc: pauk.denis, Bernhard Seibold, Andy Shevchenko, Guenter Roeck,
	Jean Delvare, linux-hwmon, linux-kernel

Prepare for platform specific callbacks usage:
* Rearrange code for directly use struct nct6775_sio_data in superio_*()
  functions.
* Use superio function pointers in nct6775_sio_data struct instead direct
  calls.
* Use nct6775 function pointers in struct nct6775_data instead direct
  calls.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Co-developed-by: Bernhard Seibold <mail@bernhard-seibold.de>
Signed-off-by: Bernhard Seibold <mail@bernhard-seibold.de>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>

---
Changes in v3:
  - Use nct6775 function pointers in struct nct6775_data instead direct calls.
  - make function declarations one line.

Changes in v2:
  - Split changes to separate patches.
  - Rearrange code for directly use struct nct6775_sio_data in superio_*()
    functions.
---
 drivers/hwmon/nct6775.c | 465 +++++++++++++++++++++-------------------
 1 file changed, 247 insertions(+), 218 deletions(-)

diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 5bd15622a85f..a3adfce8dbb8 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -133,30 +133,46 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
 
 enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
 
-static inline void
-superio_outb(int ioreg, int reg, int val)
+struct nct6775_sio_data {
+	int sioreg;
+	enum kinds kind;
+
+	/* superio_() callbacks  */
+	void (*outb)(struct nct6775_sio_data *sio_data, int reg, int val);
+	int (*inb)(struct nct6775_sio_data *sio_data, int reg);
+	void (*select)(struct nct6775_sio_data *sio_data, int ld);
+	int (*enter)(struct nct6775_sio_data *sio_data);
+	void (*exit)(struct nct6775_sio_data *sio_data);
+};
+
+static void superio_outb(struct nct6775_sio_data *sio_data, int reg, int val)
 {
+	int ioreg = sio_data->sioreg;
+
 	outb(reg, ioreg);
 	outb(val, ioreg + 1);
 }
 
-static inline int
-superio_inb(int ioreg, int reg)
+static int superio_inb(struct nct6775_sio_data *sio_data, int reg)
 {
+	int ioreg = sio_data->sioreg;
+
 	outb(reg, ioreg);
 	return inb(ioreg + 1);
 }
 
-static inline void
-superio_select(int ioreg, int ld)
+static void superio_select(struct nct6775_sio_data *sio_data, int ld)
 {
+	int ioreg = sio_data->sioreg;
+
 	outb(SIO_REG_LDSEL, ioreg);
 	outb(ld, ioreg + 1);
 }
 
-static inline int
-superio_enter(int ioreg)
+static int superio_enter(struct nct6775_sio_data *sio_data)
 {
+	int ioreg = sio_data->sioreg;
+
 	/*
 	 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
 	 */
@@ -169,9 +185,10 @@ superio_enter(int ioreg)
 	return 0;
 }
 
-static inline void
-superio_exit(int ioreg)
+static void superio_exit(struct nct6775_sio_data *sio_data)
 {
+	int ioreg = sio_data->sioreg;
+
 	outb(0xaa, ioreg);
 	outb(0x02, ioreg);
 	outb(0x02, ioreg + 1);
@@ -1215,11 +1232,10 @@ struct nct6775_data {
 	u8 fandiv1;
 	u8 fandiv2;
 	u8 sio_reg_enable;
-};
 
-struct nct6775_sio_data {
-	int sioreg;
-	enum kinds kind;
+	/* nct6775_*() callbacks  */
+	u16 (*read_value)(struct nct6775_data *data, u16 reg);
+	int (*write_value)(struct nct6775_data *data, u16 reg, u16 value);
 };
 
 struct sensor_device_template {
@@ -1459,7 +1475,7 @@ static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
 {
 	u16 res;
 
-	res = nct6775_read_value(data, reg);
+	res = data->read_value(data, reg);
 	if (!is_word_sized(data, reg))
 		res <<= 8;
 
@@ -1470,7 +1486,7 @@ static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
 {
 	if (!is_word_sized(data, reg))
 		value >>= 8;
-	return nct6775_write_value(data, reg, value);
+	return data->write_value(data, reg, value);
 }
 
 /* This function assumes that the caller holds data->update_lock */
@@ -1480,24 +1496,24 @@ static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
 
 	switch (nr) {
 	case 0:
-		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
+		reg = (data->read_value(data, NCT6775_REG_FANDIV1) & 0x70)
 		    | (data->fan_div[0] & 0x7);
-		nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
+		data->write_value(data, NCT6775_REG_FANDIV1, reg);
 		break;
 	case 1:
-		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
+		reg = (data->read_value(data, NCT6775_REG_FANDIV1) & 0x7)
 		    | ((data->fan_div[1] << 4) & 0x70);
-		nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
+		data->write_value(data, NCT6775_REG_FANDIV1, reg);
 		break;
 	case 2:
-		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
+		reg = (data->read_value(data, NCT6775_REG_FANDIV2) & 0x70)
 		    | (data->fan_div[2] & 0x7);
-		nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
+		data->write_value(data, NCT6775_REG_FANDIV2, reg);
 		break;
 	case 3:
-		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
+		reg = (data->read_value(data, NCT6775_REG_FANDIV2) & 0x7)
 		    | ((data->fan_div[3] << 4) & 0x70);
-		nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
+		data->write_value(data, NCT6775_REG_FANDIV2, reg);
 		break;
 	}
 }
@@ -1512,10 +1528,10 @@ static void nct6775_update_fan_div(struct nct6775_data *data)
 {
 	u8 i;
 
-	i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
+	i = data->read_value(data, NCT6775_REG_FANDIV1);
 	data->fan_div[0] = i & 0x7;
 	data->fan_div[1] = (i & 0x70) >> 4;
-	i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
+	i = data->read_value(data, NCT6775_REG_FANDIV2);
 	data->fan_div[2] = i & 0x7;
 	if (data->has_fan & BIT(3))
 		data->fan_div[3] = (i & 0x70) >> 4;
@@ -1563,11 +1579,11 @@ static void nct6775_init_fan_common(struct device *dev,
 	 */
 	for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
 		if (data->has_fan_min & BIT(i)) {
-			reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
+			reg = data->read_value(data, data->REG_FAN_MIN[i]);
 			if (!reg)
-				nct6775_write_value(data, data->REG_FAN_MIN[i],
-						    data->has_fan_div ? 0xff
-								      : 0xff1f);
+				data->write_value(data, data->REG_FAN_MIN[i],
+						  data->has_fan_div ? 0xff
+								    : 0xff1f);
 		}
 	}
 }
@@ -1611,8 +1627,8 @@ static void nct6775_select_fan_div(struct device *dev,
 			}
 			if (fan_min != data->fan_min[nr]) {
 				data->fan_min[nr] = fan_min;
-				nct6775_write_value(data, data->REG_FAN_MIN[nr],
-						    fan_min);
+				data->write_value(data, data->REG_FAN_MIN[nr],
+						  fan_min);
 			}
 		}
 		data->fan_div[nr] = fan_div;
@@ -1632,15 +1648,15 @@ static void nct6775_update_pwm(struct device *dev)
 			continue;
 
 		duty_is_dc = data->REG_PWM_MODE[i] &&
-		  (nct6775_read_value(data, data->REG_PWM_MODE[i])
+		  (data->read_value(data, data->REG_PWM_MODE[i])
 		   & data->PWM_MODE_MASK[i]);
 		data->pwm_mode[i] = !duty_is_dc;
 
-		fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
+		fanmodecfg = data->read_value(data, data->REG_FAN_MODE[i]);
 		for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
 			if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
 				data->pwm[j][i]
-				  = nct6775_read_value(data,
+				  = data->read_value(data,
 						       data->REG_PWM[j][i]);
 			}
 		}
@@ -1656,17 +1672,17 @@ static void nct6775_update_pwm(struct device *dev)
 			u8 t = fanmodecfg & 0x0f;
 
 			if (data->REG_TOLERANCE_H) {
-				t |= (nct6775_read_value(data,
+				t |= (data->read_value(data,
 				      data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
 			}
 			data->target_speed_tolerance[i] = t;
 		}
 
 		data->temp_tolerance[1][i] =
-			nct6775_read_value(data,
-					data->REG_CRITICAL_TEMP_TOLERANCE[i]);
+			data->read_value(data,
+					 data->REG_CRITICAL_TEMP_TOLERANCE[i]);
 
-		reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
+		reg = data->read_value(data, data->REG_TEMP_SEL[i]);
 		data->pwm_temp_sel[i] = reg & 0x1f;
 		/* If fan can stop, report floor as 0 */
 		if (reg & 0x80)
@@ -1675,7 +1691,7 @@ static void nct6775_update_pwm(struct device *dev)
 		if (!data->REG_WEIGHT_TEMP_SEL[i])
 			continue;
 
-		reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
+		reg = data->read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
 		data->pwm_weight_temp_sel[i] = reg & 0x1f;
 		/* If weight is disabled, report weight source as 0 */
 		if (!(reg & 0x80))
@@ -1684,8 +1700,8 @@ static void nct6775_update_pwm(struct device *dev)
 		/* Weight temp data */
 		for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
 			data->weight_temp[j][i]
-			  = nct6775_read_value(data,
-					       data->REG_WEIGHT_TEMP[j][i]);
+			  = data->read_value(data,
+					     data->REG_WEIGHT_TEMP[j][i]);
 		}
 	}
 }
@@ -1703,10 +1719,10 @@ static void nct6775_update_pwm_limits(struct device *dev)
 
 		for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
 			data->fan_time[j][i] =
-			  nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
+			  data->read_value(data, data->REG_FAN_TIME[j][i]);
 		}
 
-		reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
+		reg_t = data->read_value(data, data->REG_TARGET[i]);
 		/* Update only in matching mode or if never updated */
 		if (!data->target_temp[i] ||
 		    data->pwm_enable[i] == thermal_cruise)
@@ -1714,7 +1730,7 @@ static void nct6775_update_pwm_limits(struct device *dev)
 		if (!data->target_speed[i] ||
 		    data->pwm_enable[i] == speed_cruise) {
 			if (data->REG_TOLERANCE_H) {
-				reg_t |= (nct6775_read_value(data,
+				reg_t |= (data->read_value(data,
 					data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
 			}
 			data->target_speed[i] = reg_t;
@@ -1722,21 +1738,21 @@ static void nct6775_update_pwm_limits(struct device *dev)
 
 		for (j = 0; j < data->auto_pwm_num; j++) {
 			data->auto_pwm[i][j] =
-			  nct6775_read_value(data,
-					     NCT6775_AUTO_PWM(data, i, j));
+			  data->read_value(data,
+					   NCT6775_AUTO_PWM(data, i, j));
 			data->auto_temp[i][j] =
-			  nct6775_read_value(data,
-					     NCT6775_AUTO_TEMP(data, i, j));
+			  data->read_value(data,
+					   NCT6775_AUTO_TEMP(data, i, j));
 		}
 
 		/* critical auto_pwm temperature data */
 		data->auto_temp[i][data->auto_pwm_num] =
-			nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
+			data->read_value(data, data->REG_CRITICAL_TEMP[i]);
 
 		switch (data->kind) {
 		case nct6775:
-			reg = nct6775_read_value(data,
-						 NCT6775_REG_CRITICAL_ENAB[i]);
+			reg = data->read_value(data,
+					       NCT6775_REG_CRITICAL_ENAB[i]);
 			data->auto_pwm[i][data->auto_pwm_num] =
 						(reg & 0x02) ? 0xff : 0x00;
 			break;
@@ -1753,10 +1769,10 @@ static void nct6775_update_pwm_limits(struct device *dev)
 		case nct6796:
 		case nct6797:
 		case nct6798:
-			reg = nct6775_read_value(data,
+			reg = data->read_value(data,
 					data->REG_CRITICAL_PWM_ENABLE[i]);
 			if (reg & data->CRITICAL_PWM_ENABLE_MASK)
-				reg = nct6775_read_value(data,
+				reg = data->read_value(data,
 					data->REG_CRITICAL_PWM[i]);
 			else
 				reg = 0xff;
@@ -1783,11 +1799,11 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
 			if (!(data->have_in & BIT(i)))
 				continue;
 
-			data->in[i][0] = nct6775_read_value(data,
-							    data->REG_VIN[i]);
-			data->in[i][1] = nct6775_read_value(data,
+			data->in[i][0] = data->read_value(data,
+							  data->REG_VIN[i]);
+			data->in[i][1] = data->read_value(data,
 					  data->REG_IN_MINMAX[0][i]);
-			data->in[i][2] = nct6775_read_value(data,
+			data->in[i][2] = data->read_value(data,
 					  data->REG_IN_MINMAX[1][i]);
 		}
 
@@ -1798,18 +1814,18 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
 			if (!(data->has_fan & BIT(i)))
 				continue;
 
-			reg = nct6775_read_value(data, data->REG_FAN[i]);
+			reg = data->read_value(data, data->REG_FAN[i]);
 			data->rpm[i] = data->fan_from_reg(reg,
 							  data->fan_div[i]);
 
 			if (data->has_fan_min & BIT(i))
-				data->fan_min[i] = nct6775_read_value(data,
+				data->fan_min[i] = data->read_value(data,
 					   data->REG_FAN_MIN[i]);
 
 			if (data->REG_FAN_PULSES[i]) {
 				data->fan_pulses[i] =
-				  (nct6775_read_value(data,
-						      data->REG_FAN_PULSES[i])
+				  (data->read_value(data,
+						    data->REG_FAN_PULSES[i])
 				   >> data->FAN_PULSE_SHIFT[i]) & 0x03;
 			}
 
@@ -1833,7 +1849,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
 			    !(data->have_temp_fixed & BIT(i)))
 				continue;
 			data->temp_offset[i]
-			  = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
+			  = data->read_value(data, data->REG_TEMP_OFFSET[i]);
 		}
 
 		data->alarms = 0;
@@ -1842,7 +1858,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
 
 			if (!data->REG_ALARM[i])
 				continue;
-			alarm = nct6775_read_value(data, data->REG_ALARM[i]);
+			alarm = data->read_value(data, data->REG_ALARM[i]);
 			data->alarms |= ((u64)alarm) << (i << 3);
 		}
 
@@ -1852,7 +1868,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
 
 			if (!data->REG_BEEP[i])
 				continue;
-			beep = nct6775_read_value(data, data->REG_BEEP[i]);
+			beep = data->read_value(data, data->REG_BEEP[i]);
 			data->beeps |= ((u64)beep) << (i << 3);
 		}
 
@@ -1894,8 +1910,8 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
 		return err;
 	mutex_lock(&data->update_lock);
 	data->in[nr][index] = in_to_reg(val, nr);
-	nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr],
-			    data->in[nr][index]);
+	data->write_value(data, data->REG_IN_MINMAX[index - 1][nr],
+			  data->in[nr][index]);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -1919,8 +1935,8 @@ static int find_temp_source(struct nct6775_data *data, int index, int count)
 	for (nr = 0; nr < count; nr++) {
 		int src;
 
-		src = nct6775_read_value(data,
-					 data->REG_TEMP_SOURCE[nr]) & 0x1f;
+		src = data->read_value(data,
+				       data->REG_TEMP_SOURCE[nr]) & 0x1f;
 		if (src == source)
 			return nr;
 	}
@@ -1981,8 +1997,8 @@ store_beep(struct device *dev, struct device_attribute *attr, const char *buf,
 		data->beeps |= (1ULL << nr);
 	else
 		data->beeps &= ~(1ULL << nr);
-	nct6775_write_value(data, data->REG_BEEP[regindex],
-			    (data->beeps >> (regindex << 3)) & 0xff);
+	data->write_value(data, data->REG_BEEP[regindex],
+			  (data->beeps >> (regindex << 3)) & 0xff);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -2037,8 +2053,8 @@ store_temp_beep(struct device *dev, struct device_attribute *attr,
 		data->beeps |= (1ULL << bit);
 	else
 		data->beeps &= ~(1ULL << bit);
-	nct6775_write_value(data, data->REG_BEEP[regindex],
-			    (data->beeps >> (regindex << 3)) & 0xff);
+	data->write_value(data, data->REG_BEEP[regindex],
+			  (data->beeps >> (regindex << 3)) & 0xff);
 	mutex_unlock(&data->update_lock);
 
 	return count;
@@ -2205,7 +2221,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
 	}
 
 write_min:
-	nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
+	data->write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
 	mutex_unlock(&data->update_lock);
 
 	return count;
@@ -2241,10 +2257,10 @@ store_fan_pulses(struct device *dev, struct device_attribute *attr,
 
 	mutex_lock(&data->update_lock);
 	data->fan_pulses[nr] = val & 3;
-	reg = nct6775_read_value(data, data->REG_FAN_PULSES[nr]);
+	reg = data->read_value(data, data->REG_FAN_PULSES[nr]);
 	reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]);
 	reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr];
-	nct6775_write_value(data, data->REG_FAN_PULSES[nr], reg);
+	data->write_value(data, data->REG_FAN_PULSES[nr], reg);
 	mutex_unlock(&data->update_lock);
 
 	return count;
@@ -2378,7 +2394,7 @@ store_temp_offset(struct device *dev, struct device_attribute *attr,
 
 	mutex_lock(&data->update_lock);
 	data->temp_offset[nr] = val;
-	nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
+	data->write_value(data, data->REG_TEMP_OFFSET[nr], val);
 	mutex_unlock(&data->update_lock);
 
 	return count;
@@ -2417,8 +2433,8 @@ store_temp_type(struct device *dev, struct device_attribute *attr,
 	data->temp_type[nr] = val;
 	vbit = 0x02 << nr;
 	dbit = data->DIODE_MASK << nr;
-	vbat = nct6775_read_value(data, data->REG_VBAT) & ~vbit;
-	diode = nct6775_read_value(data, data->REG_DIODE) & ~dbit;
+	vbat = data->read_value(data, data->REG_VBAT) & ~vbit;
+	diode = data->read_value(data, data->REG_DIODE) & ~dbit;
 	switch (val) {
 	case 1:	/* CPU diode (diode, current mode) */
 		vbat |= vbit;
@@ -2430,8 +2446,8 @@ store_temp_type(struct device *dev, struct device_attribute *attr,
 	case 4:	/* thermistor */
 		break;
 	}
-	nct6775_write_value(data, data->REG_VBAT, vbat);
-	nct6775_write_value(data, data->REG_DIODE, diode);
+	data->write_value(data, data->REG_VBAT, vbat);
+	data->write_value(data, data->REG_DIODE, diode);
 
 	mutex_unlock(&data->update_lock);
 	return count;
@@ -2555,11 +2571,11 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 
 	mutex_lock(&data->update_lock);
 	data->pwm_mode[nr] = val;
-	reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
+	reg = data->read_value(data, data->REG_PWM_MODE[nr]);
 	reg &= ~data->PWM_MODE_MASK[nr];
 	if (!val)
 		reg |= data->PWM_MODE_MASK[nr];
-	nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
+	data->write_value(data, data->REG_PWM_MODE[nr], reg);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -2578,7 +2594,7 @@ show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
 	 * Otherwise, show the configured value.
 	 */
 	if (index == 0 && data->pwm_enable[nr] > manual)
-		pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
+		pwm = data->read_value(data, data->REG_PWM_READ[nr]);
 	else
 		pwm = data->pwm[index][nr];
 
@@ -2607,13 +2623,13 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
 
 	mutex_lock(&data->update_lock);
 	data->pwm[index][nr] = val;
-	nct6775_write_value(data, data->REG_PWM[index][nr], val);
+	data->write_value(data, data->REG_PWM[index][nr], val);
 	if (index == 2)	{ /* floor: disable if val == 0 */
-		reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
+		reg = data->read_value(data, data->REG_TEMP_SEL[nr]);
 		reg &= 0x7f;
 		if (val)
 			reg |= 0x80;
-		nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
+		data->write_value(data, data->REG_TEMP_SEL[nr], reg);
 	}
 	mutex_unlock(&data->update_lock);
 	return count;
@@ -2652,29 +2668,29 @@ static void pwm_update_registers(struct nct6775_data *data, int nr)
 	case manual:
 		break;
 	case speed_cruise:
-		reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
+		reg = data->read_value(data, data->REG_FAN_MODE[nr]);
 		reg = (reg & ~data->tolerance_mask) |
 		  (data->target_speed_tolerance[nr] & data->tolerance_mask);
-		nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
-		nct6775_write_value(data, data->REG_TARGET[nr],
+		data->write_value(data, data->REG_FAN_MODE[nr], reg);
+		data->write_value(data, data->REG_TARGET[nr],
 				    data->target_speed[nr] & 0xff);
 		if (data->REG_TOLERANCE_H) {
 			reg = (data->target_speed[nr] >> 8) & 0x0f;
 			reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
-			nct6775_write_value(data,
-					    data->REG_TOLERANCE_H[nr],
-					    reg);
+			data->write_value(data,
+					  data->REG_TOLERANCE_H[nr],
+					  reg);
 		}
 		break;
 	case thermal_cruise:
-		nct6775_write_value(data, data->REG_TARGET[nr],
-				    data->target_temp[nr]);
+		data->write_value(data, data->REG_TARGET[nr],
+				  data->target_temp[nr]);
 		fallthrough;
 	default:
-		reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
+		reg = data->read_value(data, data->REG_FAN_MODE[nr]);
 		reg = (reg & ~data->tolerance_mask) |
 		  data->temp_tolerance[0][nr];
-		nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
+		data->write_value(data, data->REG_FAN_MODE[nr], reg);
 		break;
 	}
 }
@@ -2722,13 +2738,13 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
 		 * turn off pwm control: select manual mode, set pwm to maximum
 		 */
 		data->pwm[0][nr] = 255;
-		nct6775_write_value(data, data->REG_PWM[0][nr], 255);
+		data->write_value(data, data->REG_PWM[0][nr], 255);
 	}
 	pwm_update_registers(data, nr);
-	reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
+	reg = data->read_value(data, data->REG_FAN_MODE[nr]);
 	reg &= 0x0f;
 	reg |= pwm_enable_to_reg(val) << 4;
-	nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
+	data->write_value(data, data->REG_FAN_MODE[nr], reg);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -2781,10 +2797,10 @@ store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
 	mutex_lock(&data->update_lock);
 	src = data->temp_src[val - 1];
 	data->pwm_temp_sel[nr] = src;
-	reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
+	reg = data->read_value(data, data->REG_TEMP_SEL[nr]);
 	reg &= 0xe0;
 	reg |= src;
-	nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
+	data->write_value(data, data->REG_TEMP_SEL[nr], reg);
 	mutex_unlock(&data->update_lock);
 
 	return count;
@@ -2826,15 +2842,15 @@ store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
 	if (val) {
 		src = data->temp_src[val - 1];
 		data->pwm_weight_temp_sel[nr] = src;
-		reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
+		reg = data->read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
 		reg &= 0xe0;
 		reg |= (src | 0x80);
-		nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
+		data->write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
 	} else {
 		data->pwm_weight_temp_sel[nr] = 0;
-		reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
+		reg = data->read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
 		reg &= 0x7f;
-		nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
+		data->write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
 	}
 	mutex_unlock(&data->update_lock);
 
@@ -2946,9 +2962,9 @@ store_temp_tolerance(struct device *dev, struct device_attribute *attr,
 	if (index)
 		pwm_update_registers(data, nr);
 	else
-		nct6775_write_value(data,
-				    data->REG_CRITICAL_TEMP_TOLERANCE[nr],
-				    val);
+		data->write_value(data,
+				  data->REG_CRITICAL_TEMP_TOLERANCE[nr],
+				  val);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -3071,7 +3087,7 @@ store_weight_temp(struct device *dev, struct device_attribute *attr,
 
 	mutex_lock(&data->update_lock);
 	data->weight_temp[index][nr] = val;
-	nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
+	data->write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -3120,7 +3136,7 @@ store_fan_time(struct device *dev, struct device_attribute *attr,
 	val = step_time_to_reg(val, data->pwm_mode[nr]);
 	mutex_lock(&data->update_lock);
 	data->fan_time[index][nr] = val;
-	nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
+	data->write_value(data, data->REG_FAN_TIME[index][nr], val);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -3162,21 +3178,21 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
 	mutex_lock(&data->update_lock);
 	data->auto_pwm[nr][point] = val;
 	if (point < data->auto_pwm_num) {
-		nct6775_write_value(data,
+		data->write_value(data,
 				    NCT6775_AUTO_PWM(data, nr, point),
 				    data->auto_pwm[nr][point]);
 	} else {
 		switch (data->kind) {
 		case nct6775:
 			/* disable if needed (pwm == 0) */
-			reg = nct6775_read_value(data,
-						 NCT6775_REG_CRITICAL_ENAB[nr]);
+			reg = data->read_value(data,
+					       NCT6775_REG_CRITICAL_ENAB[nr]);
 			if (val)
 				reg |= 0x02;
 			else
 				reg &= ~0x02;
-			nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
-					    reg);
+			data->write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
+					  reg);
 			break;
 		case nct6776:
 			break; /* always enabled, nothing to do */
@@ -3190,17 +3206,17 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
 		case nct6796:
 		case nct6797:
 		case nct6798:
-			nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
+			data->write_value(data, data->REG_CRITICAL_PWM[nr],
 					    val);
-			reg = nct6775_read_value(data,
+			reg = data->read_value(data,
 					data->REG_CRITICAL_PWM_ENABLE[nr]);
 			if (val == 255)
 				reg &= ~data->CRITICAL_PWM_ENABLE_MASK;
 			else
 				reg |= data->CRITICAL_PWM_ENABLE_MASK;
-			nct6775_write_value(data,
-					    data->REG_CRITICAL_PWM_ENABLE[nr],
-					    reg);
+			data->write_value(data,
+					  data->REG_CRITICAL_PWM_ENABLE[nr],
+					  reg);
 			break;
 		}
 	}
@@ -3243,11 +3259,11 @@ store_auto_temp(struct device *dev, struct device_attribute *attr,
 	mutex_lock(&data->update_lock);
 	data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
 	if (point < data->auto_pwm_num) {
-		nct6775_write_value(data,
+		data->write_value(data,
 				    NCT6775_AUTO_TEMP(data, nr, point),
 				    data->auto_temp[nr][point]);
 	} else {
-		nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
+		data->write_value(data, data->REG_CRITICAL_TEMP[nr],
 				    data->auto_temp[nr][point]);
 	}
 	mutex_unlock(&data->update_lock);
@@ -3410,6 +3426,7 @@ clear_caseopen(struct device *dev, struct device_attribute *attr,
 	       const char *buf, size_t count)
 {
 	struct nct6775_data *data = dev_get_drvdata(dev);
+	struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
 	int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
 	unsigned long val;
 	u8 reg;
@@ -3425,19 +3442,19 @@ clear_caseopen(struct device *dev, struct device_attribute *attr,
 	 * The CR registers are the same for all chips, and not all chips
 	 * support clearing the caseopen status through "regular" registers.
 	 */
-	ret = superio_enter(data->sioreg);
+	ret = sio_data->enter(sio_data);
 	if (ret) {
 		count = ret;
 		goto error;
 	}
 
-	superio_select(data->sioreg, NCT6775_LD_ACPI);
-	reg = superio_inb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
+	sio_data->select(sio_data, NCT6775_LD_ACPI);
+	reg = sio_data->inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
 	reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
-	superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
+	sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
 	reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
-	superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
-	superio_exit(data->sioreg);
+	sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
+	sio_data->exit(sio_data);
 
 	data->valid = false;	/* Force cache refresh */
 error:
@@ -3506,9 +3523,9 @@ static inline void nct6775_init_device(struct nct6775_data *data)
 
 	/* Start monitoring if needed */
 	if (data->REG_CONFIG) {
-		tmp = nct6775_read_value(data, data->REG_CONFIG);
+		tmp = data->read_value(data, data->REG_CONFIG);
 		if (!(tmp & 0x01))
-			nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
+			data->write_value(data, data->REG_CONFIG, tmp | 0x01);
 	}
 
 	/* Enable temperature sensors if needed */
@@ -3517,18 +3534,18 @@ static inline void nct6775_init_device(struct nct6775_data *data)
 			continue;
 		if (!data->reg_temp_config[i])
 			continue;
-		tmp = nct6775_read_value(data, data->reg_temp_config[i]);
+		tmp = data->read_value(data, data->reg_temp_config[i]);
 		if (tmp & 0x01)
-			nct6775_write_value(data, data->reg_temp_config[i],
+			data->write_value(data, data->reg_temp_config[i],
 					    tmp & 0xfe);
 	}
 
 	/* Enable VBAT monitoring if needed */
-	tmp = nct6775_read_value(data, data->REG_VBAT);
+	tmp = data->read_value(data, data->REG_VBAT);
 	if (!(tmp & 0x01))
-		nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
+		data->write_value(data, data->REG_VBAT, tmp | 0x01);
 
-	diode = nct6775_read_value(data, data->REG_DIODE);
+	diode = data->read_value(data, data->REG_DIODE);
 
 	for (i = 0; i < data->temp_fixed_num; i++) {
 		if (!(data->have_temp_fixed & BIT(i)))
@@ -3542,29 +3559,29 @@ static inline void nct6775_init_device(struct nct6775_data *data)
 }
 
 static void
-nct6775_check_fan_inputs(struct nct6775_data *data)
+nct6775_check_fan_inputs(struct nct6775_data *data,
+		struct nct6775_sio_data *sio_data)
 {
 	bool fan3pin = false, fan4pin = false, fan4min = false;
 	bool fan5pin = false, fan6pin = false, fan7pin = false;
 	bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
 	bool pwm6pin = false, pwm7pin = false;
-	int sioreg = data->sioreg;
 
 	/* Store SIO_REG_ENABLE for use during resume */
-	superio_select(sioreg, NCT6775_LD_HWM);
-	data->sio_reg_enable = superio_inb(sioreg, SIO_REG_ENABLE);
+	sio_data->select(sio_data, NCT6775_LD_HWM);
+	data->sio_reg_enable = sio_data->inb(sio_data, SIO_REG_ENABLE);
 
 	/* fan4 and fan5 share some pins with the GPIO and serial flash */
 	if (data->kind == nct6775) {
-		int cr2c = superio_inb(sioreg, 0x2c);
+		int cr2c = sio_data->inb(sio_data, 0x2c);
 
 		fan3pin = cr2c & BIT(6);
 		pwm3pin = cr2c & BIT(7);
 
 		/* On NCT6775, fan4 shares pins with the fdc interface */
-		fan4pin = !(superio_inb(sioreg, 0x2A) & 0x80);
+		fan4pin = !(sio_data->inb(sio_data, 0x2A) & 0x80);
 	} else if (data->kind == nct6776) {
-		bool gpok = superio_inb(sioreg, 0x27) & 0x80;
+		bool gpok = sio_data->inb(sio_data, 0x27) & 0x80;
 		const char *board_vendor, *board_name;
 
 		board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -3580,7 +3597,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
 			if (!strcmp(board_name, "Z77 Pro4-M")) {
 				if ((data->sio_reg_enable & 0xe0) != 0xe0) {
 					data->sio_reg_enable |= 0xe0;
-					superio_outb(sioreg, SIO_REG_ENABLE,
+					sio_data->outb(sio_data, SIO_REG_ENABLE,
 						     data->sio_reg_enable);
 				}
 			}
@@ -3589,32 +3606,32 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
 		if (data->sio_reg_enable & 0x80)
 			fan3pin = gpok;
 		else
-			fan3pin = !(superio_inb(sioreg, 0x24) & 0x40);
+			fan3pin = !(sio_data->inb(sio_data, 0x24) & 0x40);
 
 		if (data->sio_reg_enable & 0x40)
 			fan4pin = gpok;
 		else
-			fan4pin = superio_inb(sioreg, 0x1C) & 0x01;
+			fan4pin = sio_data->inb(sio_data, 0x1C) & 0x01;
 
 		if (data->sio_reg_enable & 0x20)
 			fan5pin = gpok;
 		else
-			fan5pin = superio_inb(sioreg, 0x1C) & 0x02;
+			fan5pin = sio_data->inb(sio_data, 0x1C) & 0x02;
 
 		fan4min = fan4pin;
 		pwm3pin = fan3pin;
 	} else if (data->kind == nct6106) {
-		int cr24 = superio_inb(sioreg, 0x24);
+		int cr24 = sio_data->inb(sio_data, 0x24);
 
 		fan3pin = !(cr24 & 0x80);
 		pwm3pin = cr24 & 0x08;
 	} else if (data->kind == nct6116) {
-		int cr1a = superio_inb(sioreg, 0x1a);
-		int cr1b = superio_inb(sioreg, 0x1b);
-		int cr24 = superio_inb(sioreg, 0x24);
-		int cr2a = superio_inb(sioreg, 0x2a);
-		int cr2b = superio_inb(sioreg, 0x2b);
-		int cr2f = superio_inb(sioreg, 0x2f);
+		int cr1a = sio_data->inb(sio_data, 0x1a);
+		int cr1b = sio_data->inb(sio_data, 0x1b);
+		int cr24 = sio_data->inb(sio_data, 0x24);
+		int cr2a = sio_data->inb(sio_data, 0x2a);
+		int cr2b = sio_data->inb(sio_data, 0x2b);
+		int cr2f = sio_data->inb(sio_data, 0x2f);
 
 		fan3pin = !(cr2b & 0x10);
 		fan4pin = (cr2b & 0x80) ||			// pin 1(2)
@@ -3630,24 +3647,24 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
 		 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
 		 * NCT6797D, NCT6798D
 		 */
-		int cr1a = superio_inb(sioreg, 0x1a);
-		int cr1b = superio_inb(sioreg, 0x1b);
-		int cr1c = superio_inb(sioreg, 0x1c);
-		int cr1d = superio_inb(sioreg, 0x1d);
-		int cr2a = superio_inb(sioreg, 0x2a);
-		int cr2b = superio_inb(sioreg, 0x2b);
-		int cr2d = superio_inb(sioreg, 0x2d);
-		int cr2f = superio_inb(sioreg, 0x2f);
+		int cr1a = sio_data->inb(sio_data, 0x1a);
+		int cr1b = sio_data->inb(sio_data, 0x1b);
+		int cr1c = sio_data->inb(sio_data, 0x1c);
+		int cr1d = sio_data->inb(sio_data, 0x1d);
+		int cr2a = sio_data->inb(sio_data, 0x2a);
+		int cr2b = sio_data->inb(sio_data, 0x2b);
+		int cr2d = sio_data->inb(sio_data, 0x2d);
+		int cr2f = sio_data->inb(sio_data, 0x2f);
 		bool dsw_en = cr2f & BIT(3);
 		bool ddr4_en = cr2f & BIT(4);
 		int cre0;
 		int creb;
 		int cred;
 
-		superio_select(sioreg, NCT6775_LD_12);
-		cre0 = superio_inb(sioreg, 0xe0);
-		creb = superio_inb(sioreg, 0xeb);
-		cred = superio_inb(sioreg, 0xed);
+		sio_data->select(sio_data, NCT6775_LD_12);
+		cre0 = sio_data->inb(sio_data, 0xe0);
+		creb = sio_data->inb(sio_data, 0xeb);
+		cred = sio_data->inb(sio_data, 0xed);
 
 		fan3pin = !(cr1c & BIT(5));
 		fan4pin = !(cr1c & BIT(6));
@@ -3774,7 +3791,7 @@ static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
 
 		if (!regp[i])
 			continue;
-		src = nct6775_read_value(data, regp[i]);
+		src = data->read_value(data, regp[i]);
 		src &= 0x1f;
 		if (!src || (*mask & BIT(src)))
 			continue;
@@ -3782,7 +3799,7 @@ static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
 			continue;
 
 		index = __ffs(*available);
-		nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
+		data->write_value(data, data->REG_TEMP_SOURCE[index], src);
 		*available &= ~BIT(index);
 		*mask |= BIT(src);
 	}
@@ -3793,7 +3810,7 @@ static int nct6775_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
 	struct nct6775_data *data;
-	struct resource *res;
+	struct resource *res = NULL;
 	int i, s, err = 0;
 	int src, mask, available;
 	const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
@@ -3806,6 +3823,9 @@ static int nct6775_probe(struct platform_device *pdev)
 	int num_attr_groups = 0;
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (!res)
+		return -EBUSY;
+
 	if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
 				 DRVNAME))
 		return -EBUSY;
@@ -3818,6 +3838,8 @@ static int nct6775_probe(struct platform_device *pdev)
 	data->kind = sio_data->kind;
 	data->sioreg = sio_data->sioreg;
 	data->addr = res->start;
+	data->read_value = nct6775_read_value;
+	data->write_value = nct6775_write_value;
 	mutex_init(&data->update_lock);
 	data->name = nct6775_device_names[data->kind];
 	data->bank = 0xff;		/* Force initial bank selection */
@@ -4337,7 +4359,7 @@ static int nct6775_probe(struct platform_device *pdev)
 		if (reg_temp[i] == 0)
 			continue;
 
-		src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
+		src = data->read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
 		if (!src || (mask & BIT(src)))
 			available |= BIT(i);
 
@@ -4357,7 +4379,7 @@ static int nct6775_probe(struct platform_device *pdev)
 		if (reg_temp[i] == 0)
 			continue;
 
-		src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
+		src = data->read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
 		if (!src || (mask & BIT(src)))
 			continue;
 
@@ -4417,7 +4439,7 @@ static int nct6775_probe(struct platform_device *pdev)
 		if (reg_temp_mon[i] == 0)
 			continue;
 
-		src = nct6775_read_value(data, data->REG_TEMP_SEL[i]) & 0x1f;
+		src = data->read_value(data, data->REG_TEMP_SEL[i]) & 0x1f;
 		if (!src)
 			continue;
 
@@ -4502,11 +4524,11 @@ static int nct6775_probe(struct platform_device *pdev)
 	/* Initialize the chip */
 	nct6775_init_device(data);
 
-	err = superio_enter(sio_data->sioreg);
+	err = sio_data->enter(sio_data);
 	if (err)
 		return err;
 
-	cr2a = superio_inb(sio_data->sioreg, 0x2a);
+	cr2a = sio_data->inb(sio_data, 0x2a);
 	switch (data->kind) {
 	case nct6775:
 		data->have_vid = (cr2a & 0x40);
@@ -4532,17 +4554,17 @@ static int nct6775_probe(struct platform_device *pdev)
 	 * We can get the VID input values directly at logical device D 0xe3.
 	 */
 	if (data->have_vid) {
-		superio_select(sio_data->sioreg, NCT6775_LD_VID);
-		data->vid = superio_inb(sio_data->sioreg, 0xe3);
+		sio_data->select(sio_data, NCT6775_LD_VID);
+		data->vid = sio_data->inb(sio_data, 0xe3);
 		data->vrm = vid_which_vrm();
 	}
 
 	if (fan_debounce) {
 		u8 tmp;
 
-		superio_select(sio_data->sioreg, NCT6775_LD_HWM);
-		tmp = superio_inb(sio_data->sioreg,
-				  NCT6775_REG_CR_FAN_DEBOUNCE);
+		sio_data->select(sio_data, NCT6775_LD_HWM);
+		tmp = sio_data->inb(sio_data,
+				    NCT6775_REG_CR_FAN_DEBOUNCE);
 		switch (data->kind) {
 		case nct6106:
 		case nct6116:
@@ -4565,15 +4587,15 @@ static int nct6775_probe(struct platform_device *pdev)
 			tmp |= 0x7e;
 			break;
 		}
-		superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
+		sio_data->outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE,
 			     tmp);
 		dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
 			 data->name);
 	}
 
-	nct6775_check_fan_inputs(data);
+	nct6775_check_fan_inputs(data, sio_data);
 
-	superio_exit(sio_data->sioreg);
+	sio_data->exit(sio_data);
 
 	/* Read fan clock dividers immediately */
 	nct6775_init_fan_common(dev, data);
@@ -4613,15 +4635,15 @@ static int nct6775_probe(struct platform_device *pdev)
 	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 
-static void nct6791_enable_io_mapping(int sioaddr)
+static void nct6791_enable_io_mapping(struct nct6775_sio_data *sio_data)
 {
 	int val;
 
-	val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
+	val = sio_data->inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
 	if (val & 0x10) {
 		pr_info("Enabling hardware monitor logical device mappings.\n");
-		superio_outb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
-			     val & ~0x10);
+		sio_data->outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
+			       val & ~0x10);
 	}
 }
 
@@ -4630,10 +4652,10 @@ static int __maybe_unused nct6775_suspend(struct device *dev)
 	struct nct6775_data *data = nct6775_update_device(dev);
 
 	mutex_lock(&data->update_lock);
-	data->vbat = nct6775_read_value(data, data->REG_VBAT);
+	data->vbat = data->read_value(data, data->REG_VBAT);
 	if (data->kind == nct6775) {
-		data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
-		data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
+		data->fandiv1 = data->read_value(data, NCT6775_REG_FANDIV1);
+		data->fandiv2 = data->read_value(data, NCT6775_REG_FANDIV2);
 	}
 	mutex_unlock(&data->update_lock);
 
@@ -4643,47 +4665,47 @@ static int __maybe_unused nct6775_suspend(struct device *dev)
 static int __maybe_unused nct6775_resume(struct device *dev)
 {
 	struct nct6775_data *data = dev_get_drvdata(dev);
-	int sioreg = data->sioreg;
+	struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
 	int i, j, err = 0;
 	u8 reg;
 
 	mutex_lock(&data->update_lock);
 	data->bank = 0xff;		/* Force initial bank selection */
 
-	err = superio_enter(sioreg);
+	err = sio_data->enter(sio_data);
 	if (err)
 		goto abort;
 
-	superio_select(sioreg, NCT6775_LD_HWM);
-	reg = superio_inb(sioreg, SIO_REG_ENABLE);
+	sio_data->select(sio_data, NCT6775_LD_HWM);
+	reg = sio_data->inb(sio_data, SIO_REG_ENABLE);
 	if (reg != data->sio_reg_enable)
-		superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable);
+		sio_data->outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
 
 	if (data->kind == nct6791 || data->kind == nct6792 ||
 	    data->kind == nct6793 || data->kind == nct6795 ||
 	    data->kind == nct6796 || data->kind == nct6797 ||
 	    data->kind == nct6798)
-		nct6791_enable_io_mapping(sioreg);
+		nct6791_enable_io_mapping(sio_data);
 
-	superio_exit(sioreg);
+	sio_data->exit(sio_data);
 
 	/* Restore limits */
 	for (i = 0; i < data->in_num; i++) {
 		if (!(data->have_in & BIT(i)))
 			continue;
 
-		nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
-				    data->in[i][1]);
-		nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
-				    data->in[i][2]);
+		data->write_value(data, data->REG_IN_MINMAX[0][i],
+				  data->in[i][1]);
+		data->write_value(data, data->REG_IN_MINMAX[1][i],
+				  data->in[i][2]);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
 		if (!(data->has_fan_min & BIT(i)))
 			continue;
 
-		nct6775_write_value(data, data->REG_FAN_MIN[i],
-				    data->fan_min[i]);
+		data->write_value(data, data->REG_FAN_MIN[i],
+				  data->fan_min[i]);
 	}
 
 	for (i = 0; i < NUM_TEMP; i++) {
@@ -4697,10 +4719,10 @@ static int __maybe_unused nct6775_resume(struct device *dev)
 	}
 
 	/* Restore other settings */
-	nct6775_write_value(data, data->REG_VBAT, data->vbat);
+	data->write_value(data, data->REG_VBAT, data->vbat);
 	if (data->kind == nct6775) {
-		nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
-		nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
+		data->write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
+		data->write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
 	}
 
 abort:
@@ -4728,12 +4750,14 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 	int err;
 	int addr;
 
-	err = superio_enter(sioaddr);
+	sio_data->sioreg = sioaddr;
+
+	err = sio_data->enter(sio_data);
 	if (err)
 		return err;
 
-	val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
-		superio_inb(sioaddr, SIO_REG_DEVID + 1);
+	val = (sio_data->inb(sio_data, SIO_REG_DEVID) << 8) |
+		sio_data->inb(sio_data, SIO_REG_DEVID + 1);
 	if (force_id && val != 0xffff)
 		val = force_id;
 
@@ -4777,38 +4801,37 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 	default:
 		if (val != 0xffff)
 			pr_debug("unsupported chip ID: 0x%04x\n", val);
-		superio_exit(sioaddr);
+		sio_data->exit(sio_data);
 		return -ENODEV;
 	}
 
 	/* We have a known chip, find the HWM I/O address */
-	superio_select(sioaddr, NCT6775_LD_HWM);
-	val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
-	    | superio_inb(sioaddr, SIO_REG_ADDR + 1);
+	sio_data->select(sio_data, NCT6775_LD_HWM);
+	val = (sio_data->inb(sio_data, SIO_REG_ADDR) << 8)
+	    | sio_data->inb(sio_data, SIO_REG_ADDR + 1);
 	addr = val & IOREGION_ALIGNMENT;
 	if (addr == 0) {
 		pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
-		superio_exit(sioaddr);
+		sio_data->exit(sio_data);
 		return -ENODEV;
 	}
 
 	/* Activate logical device if needed */
-	val = superio_inb(sioaddr, SIO_REG_ENABLE);
+	val = sio_data->inb(sio_data, SIO_REG_ENABLE);
 	if (!(val & 0x01)) {
 		pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
-		superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
+		sio_data->outb(sio_data, SIO_REG_ENABLE, val | 0x01);
 	}
 
 	if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
 	    sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
 	    sio_data->kind == nct6796 || sio_data->kind == nct6797 ||
 	    sio_data->kind == nct6798)
-		nct6791_enable_io_mapping(sioaddr);
+		nct6791_enable_io_mapping(sio_data);
 
-	superio_exit(sioaddr);
+	sio_data->exit(sio_data);
 	pr_info("Found %s or compatible chip at %#x:%#x\n",
 		nct6775_sio_names[sio_data->kind], sioaddr, addr);
-	sio_data->sioreg = sioaddr;
 
 	return addr;
 }
@@ -4842,6 +4865,12 @@ static int __init sensors_nct6775_init(void)
 	 * nct6775 hardware monitor, and call probe()
 	 */
 	for (i = 0; i < ARRAY_SIZE(pdev); i++) {
+		sio_data.outb = superio_outb;
+		sio_data.inb = superio_inb;
+		sio_data.select = superio_select;
+		sio_data.enter = superio_enter;
+		sio_data.exit = superio_exit;
+
 		address = nct6775_find(sioaddr[i], &sio_data);
 		if (address <= 0)
 			continue;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/2] hwmon: (nct6775) Support access via Asus WMI
  2021-09-12 11:05 [PATCH v3 0/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
  2021-09-12 11:05 ` [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*() Denis Pauk
@ 2021-09-12 11:05 ` Denis Pauk
  2021-09-12 12:47   ` kernel test robot
  2021-09-12 15:14 ` [PATCH v3 0/2] " Andy Shevchenko
  2 siblings, 1 reply; 7+ messages in thread
From: Denis Pauk @ 2021-09-12 11:05 UTC (permalink / raw)
  Cc: pauk.denis, Bernhard Seibold, Pär Ekholm, to.eivind,
	Artem S . Tashkinov, Vittorio Roberto Alfieri, Sahan Fernando,
	Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-hwmon,
	linux-kernel

Support accessing the NCT677x via Asus WMI functions.

On mainboards that support this way of accessing the chip, the driver will
usually not work without this option since in these mainboards, ACPI will 
mark the I/O port as used.

Code uses ACPI firmware interface to commucate with sensors with ASUS
motherboards:
* PRIME B460-PLUS,
* ROG CROSSHAIR VIII IMPACT,
* ROG STRIX B550-E GAMING,
* ROG STRIX B550-F GAMING,
* ROG STRIX B550-F GAMING (WI-FI),
* ROG STRIX Z490-I GAMING,
* TUF GAMING B550M-PLUS,
* TUF GAMING B550M-PLUS (WI-FI),
* TUF GAMING B550-PLUS,
* TUF GAMING X570-PLUS,
* TUF GAMING X570-PRO (WI-FI).

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Co-developed-by: Bernhard Seibold <mail@bernhard-seibold.de>
Signed-off-by: Bernhard Seibold <mail@bernhard-seibold.de>
Tested-by: Pär Ekholm <pehlm@pekholm.org>
Tested-by: <to.eivind@gmail.com>
Tested-by: Artem S. Tashkinov <aros@gmx.com>
Tested-by: Vittorio Roberto Alfieri <me@rebtoor.com>
Tested-by: Sahan Fernando <sahan.h.fernando@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>

---
Changes in v3:
  - Remove unrequired type conversions.
  - save result of match_string before check.

Changes in v2:
  - Split changes to separate patches.
  - Limit WMI usage by DMI_BOARD_NAME in checked ASUS motherboards.
---
 drivers/hwmon/nct6775.c | 230 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 207 insertions(+), 23 deletions(-)

diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index a3adfce8dbb8..2bf9ca6e6ff9 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -55,6 +55,7 @@
 #include <linux/dmi.h>
 #include <linux/io.h>
 #include <linux/nospec.h>
+#include <linux/wmi.h>
 #include "lm75.h"
 
 #define USE_ALTERNATE
@@ -132,10 +133,13 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
 #define SIO_ID_MASK		0xFFF8
 
 enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
+enum sensor_access { access_direct, access_asuswmi };
 
 struct nct6775_sio_data {
 	int sioreg;
+	int ld;
 	enum kinds kind;
+	enum sensor_access access;
 
 	/* superio_() callbacks  */
 	void (*outb)(struct nct6775_sio_data *sio_data, int reg, int val);
@@ -145,6 +149,84 @@ struct nct6775_sio_data {
 	void (*exit)(struct nct6775_sio_data *sio_data);
 };
 
+#define ASUSWMI_MGMT2_GUID		"466747A0-70EC-11DE-8A39-0800200C9A66"
+#define ASUSWMI_METHODID_RSIO		0x5253494F
+#define ASUSWMI_METHODID_WSIO		0x5753494F
+#define ASUSWMI_METHODID_RHWM		0x5248574D
+#define ASUSWMI_METHODID_WHWM		0x5748574D
+#define ASUSWMI_UNSUPPORTED_METHOD	0xFFFFFFFE
+
+static int asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval)
+{
+	u32 args = bank | (reg << 8) | (val << 16);
+	struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	acpi_status status;
+	union acpi_object *obj;
+	u32 tmp = 0;
+
+	status = wmi_evaluate_method(ASUSWMI_MGMT2_GUID, 0, method_id,
+				     &input, &output);
+
+	if (ACPI_FAILURE(status))
+		return -EIO;
+
+	obj = output.pointer;
+	if (obj && obj->type == ACPI_TYPE_INTEGER)
+		tmp = obj->integer.value;
+
+	if (retval)
+		*retval = tmp;
+
+	kfree(obj);
+
+	if (tmp == ASUSWMI_UNSUPPORTED_METHOD)
+		return -ENODEV;
+	return 0;
+}
+
+static inline int nct6775_asuswmi_write(u8 bank, u8 reg, u8 val)
+{
+	return asuswmi_evaluate_method(ASUSWMI_METHODID_WHWM, bank, reg, val, 0);
+}
+
+static inline int nct6775_asuswmi_read(u8 bank, u8 reg, u8 *val)
+{
+	u32 tmp;
+	int ret = asuswmi_evaluate_method(ASUSWMI_METHODID_RHWM, bank, reg, 0, &tmp);
+	*val = tmp;
+	return ret;
+}
+
+static int superio_wmi_inb(struct nct6775_sio_data *sio_data, int reg)
+{
+	int tmp;
+
+	asuswmi_evaluate_method(ASUSWMI_METHODID_RSIO,
+			sio_data->ld, reg, 0, &tmp);
+	return tmp;
+}
+
+static void superio_wmi_outb(struct nct6775_sio_data *sio_data, int reg, int val)
+{
+	asuswmi_evaluate_method(ASUSWMI_METHODID_WSIO,
+			sio_data->ld, reg, val, 0);
+}
+
+static void superio_wmi_select(struct nct6775_sio_data *sio_data, int ld)
+{
+	sio_data->ld = ld;
+}
+
+static int superio_wmi_enter(struct nct6775_sio_data *sio_data)
+{
+	return 0;
+}
+
+static void superio_wmi_exit(struct nct6775_sio_data *sio_data)
+{
+}
+
 static void superio_outb(struct nct6775_sio_data *sio_data, int reg, int val)
 {
 	int ioreg = sio_data->sioreg;
@@ -1423,6 +1505,49 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg)
 	return false;
 }
 
+static inline void nct6775_wmi_set_bank(struct nct6775_data *data, u16 reg)
+{
+	u8 bank = reg >> 8;
+
+	data->bank = bank;
+}
+
+static u16 nct6775_wmi_read_value(struct nct6775_data *data, u16 reg)
+{
+	int res, word_sized = is_word_sized(data, reg);
+	u8 tmp;
+
+	nct6775_wmi_set_bank(data, reg);
+
+	nct6775_asuswmi_read(data->bank, reg, &tmp);
+	res = (tmp & 0xff);
+	if (word_sized) {
+		nct6775_asuswmi_read(data->bank,
+				(reg & 0xff) + 1, &tmp);
+		res = (res << 8) + (tmp & 0xff);
+	}
+	return res;
+}
+
+static int nct6775_wmi_write_value(struct nct6775_data *data, u16 reg, u16 value)
+{
+	int word_sized = is_word_sized(data, reg);
+
+	nct6775_wmi_set_bank(data, reg);
+
+	if (word_sized) {
+		nct6775_asuswmi_write(data->bank, (reg & 0xff),
+				(value >> 8) & 0xff);
+		nct6775_asuswmi_write(data->bank, (reg & 0xff) + 1,
+				value & 0xff);
+	} else {
+		nct6775_asuswmi_write(data->bank, (reg & 0xff),
+				value);
+	}
+
+	return 0;
+}
+
 /*
  * On older chips, only registers 0x50-0x5f are banked.
  * On more recent chips, all registers are banked.
@@ -3822,13 +3947,15 @@ static int nct6775_probe(struct platform_device *pdev)
 	struct device *hwmon_dev;
 	int num_attr_groups = 0;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!res)
-		return -EBUSY;
+	if (sio_data->access == access_direct) {
+		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+		if (!res)
+			return -EBUSY;
 
-	if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
-				 DRVNAME))
-		return -EBUSY;
+		if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
+					 DRVNAME))
+			return -EBUSY;
+	}
 
 	data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
 			    GFP_KERNEL);
@@ -3837,9 +3964,17 @@ static int nct6775_probe(struct platform_device *pdev)
 
 	data->kind = sio_data->kind;
 	data->sioreg = sio_data->sioreg;
-	data->addr = res->start;
-	data->read_value = nct6775_read_value;
-	data->write_value = nct6775_write_value;
+
+	if (sio_data->access == access_direct) {
+		data->addr = res->start;
+		data->read_value = nct6775_read_value;
+		data->write_value = nct6775_write_value;
+	} else {
+		data->addr = 0;
+		data->read_value = nct6775_wmi_read_value;
+		data->write_value = nct6775_wmi_write_value;
+	}
+
 	mutex_init(&data->update_lock);
 	data->name = nct6775_device_names[data->kind];
 	data->bank = 0xff;		/* Force initial bank selection */
@@ -4750,6 +4885,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 	int err;
 	int addr;
 
+	sio_data->access = access_direct;
 	sio_data->sioreg = sioaddr;
 
 	err = sio_data->enter(sio_data);
@@ -4844,6 +4980,22 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
  */
 static struct platform_device *pdev[2];
 
+#define NCT6775_REG_CHIPID 0x58
+
+static const char * const asus_wmi_boards[] = {
+	"PRIME B460-PLUS",
+	"ROG CROSSHAIR VIII IMPACT",
+	"ROG STRIX B550-E GAMING",
+	"ROG STRIX B550-F GAMING",
+	"ROG STRIX B550-F GAMING (WI-FI)",
+	"ROG STRIX Z490-I GAMING",
+	"TUF GAMING B550M-PLUS",
+	"TUF GAMING B550M-PLUS (WI-FI)",
+	"TUF GAMING B550-PLUS",
+	"TUF GAMING X570-PLUS",
+	"TUF GAMING X570-PRO (WI-FI)",
+};
+
 static int __init sensors_nct6775_init(void)
 {
 	int i, err;
@@ -4852,11 +5004,30 @@ static int __init sensors_nct6775_init(void)
 	struct resource res;
 	struct nct6775_sio_data sio_data;
 	int sioaddr[2] = { 0x2e, 0x4e };
+	const char *board_vendor, *board_name;
+	enum sensor_access access = access_direct;
+	u8 tmp;
 
 	err = platform_driver_register(&nct6775_driver);
 	if (err)
 		return err;
 
+	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+	board_name = dmi_get_system_info(DMI_BOARD_NAME);
+
+	if (board_name && board_vendor &&
+	    !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
+		err = match_string(asus_wmi_boards,
+					ARRAY_SIZE(asus_wmi_boards), board_name);
+		if (err != -EINVAL) {
+			/* if reading chip id via WMI succeeds, use WMI */
+			if (!nct6775_asuswmi_read(0, NCT6775_REG_CHIPID, &tmp)) {
+				pr_info("Using Asus WMI to access chip\n");
+				access = access_asuswmi;
+			}
+		}
+	}
+
 	/*
 	 * initialize sio_data->kind and sio_data->sioreg.
 	 *
@@ -4877,6 +5048,17 @@ static int __init sensors_nct6775_init(void)
 
 		found = true;
 
+		/* Update access method */
+		sio_data.access = access;
+
+		if (access == access_asuswmi) {
+			sio_data.outb = superio_wmi_outb;
+			sio_data.inb = superio_wmi_inb;
+			sio_data.select = superio_wmi_select;
+			sio_data.enter = superio_wmi_enter;
+			sio_data.exit = superio_wmi_exit;
+		}
+
 		pdev[i] = platform_device_alloc(DRVNAME, address);
 		if (!pdev[i]) {
 			err = -ENOMEM;
@@ -4888,23 +5070,25 @@ static int __init sensors_nct6775_init(void)
 		if (err)
 			goto exit_device_put;
 
-		memset(&res, 0, sizeof(res));
-		res.name = DRVNAME;
-		res.start = address + IOREGION_OFFSET;
-		res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
-		res.flags = IORESOURCE_IO;
+		if (sio_data.access == access_direct) {
+			memset(&res, 0, sizeof(res));
+			res.name = DRVNAME;
+			res.start = address + IOREGION_OFFSET;
+			res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
+			res.flags = IORESOURCE_IO;
+
+			err = acpi_check_resource_conflict(&res);
+			if (err) {
+				platform_device_put(pdev[i]);
+				pdev[i] = NULL;
+				continue;
+			}
 
-		err = acpi_check_resource_conflict(&res);
-		if (err) {
-			platform_device_put(pdev[i]);
-			pdev[i] = NULL;
-			continue;
+			err = platform_device_add_resources(pdev[i], &res, 1);
+			if (err)
+				goto exit_device_put;
 		}
 
-		err = platform_device_add_resources(pdev[i], &res, 1);
-		if (err)
-			goto exit_device_put;
-
 		/* platform_device_add calls probe() */
 		err = platform_device_add(pdev[i]);
 		if (err)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/2] hwmon: (nct6775) Support access via Asus WMI
  2021-09-12 11:05 ` [PATCH v3 2/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
@ 2021-09-12 12:47   ` kernel test robot
  0 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-09-12 12:47 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3020 bytes --]

Hi Denis,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hwmon/hwmon-next]
[also build test ERROR on v5.14 next-20210910]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Denis-Pauk/hwmon-nct6775-Support-access-via-Asus-WMI/20210912-190749
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: ia64-randconfig-r024-20210912 (attached as .config)
compiler: ia64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5b6bc5cd3f9d089d5a31a391a7cd61350fffc073
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Denis-Pauk/hwmon-nct6775-Support-access-via-Asus-WMI/20210912-190749
        git checkout 5b6bc5cd3f9d089d5a31a391a7cd61350fffc073
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=ia64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/hwmon/nct6775.c: In function 'asuswmi_evaluate_method':
>> drivers/hwmon/nct6775.c:168:18: error: implicit declaration of function 'wmi_evaluate_method'; did you mean 'wmidev_evaluate_method'? [-Werror=implicit-function-declaration]
     168 |         status = wmi_evaluate_method(ASUSWMI_MGMT2_GUID, 0, method_id,
         |                  ^~~~~~~~~~~~~~~~~~~
         |                  wmidev_evaluate_method
   cc1: some warnings being treated as errors


vim +168 drivers/hwmon/nct6775.c

   158	
   159	static int asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval)
   160	{
   161		u32 args = bank | (reg << 8) | (val << 16);
   162		struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
   163		struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
   164		acpi_status status;
   165		union acpi_object *obj;
   166		u32 tmp = 0;
   167	
 > 168		status = wmi_evaluate_method(ASUSWMI_MGMT2_GUID, 0, method_id,
   169					     &input, &output);
   170	
   171		if (ACPI_FAILURE(status))
   172			return -EIO;
   173	
   174		obj = output.pointer;
   175		if (obj && obj->type == ACPI_TYPE_INTEGER)
   176			tmp = obj->integer.value;
   177	
   178		if (retval)
   179			*retval = tmp;
   180	
   181		kfree(obj);
   182	
   183		if (tmp == ASUSWMI_UNSUPPORTED_METHOD)
   184			return -ENODEV;
   185		return 0;
   186	}
   187	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 26292 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*().
  2021-09-12 11:05 ` [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*() Denis Pauk
@ 2021-09-12 14:50     ` kernel test robot
  0 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-09-12 14:50 UTC (permalink / raw)
  To: Denis Pauk
  Cc: kbuild-all, pauk.denis, Bernhard Seibold, Andy Shevchenko,
	Guenter Roeck, Jean Delvare, linux-hwmon, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 45855 bytes --]

Hi Denis,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hwmon/hwmon-next]
[also build test ERROR on v5.14 next-20210910]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Denis-Pauk/hwmon-nct6775-Support-access-via-Asus-WMI/20210912-190749
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: arm-randconfig-s032-20210912 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/f11f2179ea7eb747b68a65ac03fce15ff4319004
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Denis-Pauk/hwmon-nct6775-Support-access-via-Asus-WMI/20210912-190749
        git checkout f11f2179ea7eb747b68a65ac03fce15ff4319004
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arm SHELL=/bin/bash drivers/hwmon/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   drivers/hwmon/nct6775.c: In function 'clear_caseopen':
>> drivers/hwmon/nct6775.c:3452:70: error: macro "inb" passed 2 arguments, but takes just 1
    3452 |         reg = sio_data->inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3452:13: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3452 |         reg = sio_data->inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
         |             ^
>> drivers/hwmon/nct6775.c:3454:70: error: macro "outb" passed 3 arguments, but takes just 2
    3454 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:3454:17: warning: statement with no effect [-Wunused-value]
    3454 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |         ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c:3456:70: error: macro "outb" passed 3 arguments, but takes just 2
    3456 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:3456:17: warning: statement with no effect [-Wunused-value]
    3456 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |         ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6775_check_fan_inputs':
   drivers/hwmon/nct6775.c:3572:70: error: macro "inb" passed 2 arguments, but takes just 1
    3572 |         data->sio_reg_enable = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3572:30: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3572 |         data->sio_reg_enable = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                              ^
   drivers/hwmon/nct6775.c:3576:56: error: macro "inb" passed 2 arguments, but takes just 1
    3576 |                 int cr2c = sio_data->inb(sio_data, 0x2c);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3576:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3576 |                 int cr2c = sio_data->inb(sio_data, 0x2c);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3582:57: error: macro "inb" passed 2 arguments, but takes just 1
    3582 |                 fan4pin = !(sio_data->inb(sio_data, 0x2A) & 0x80);
         |                                                         ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3582:59: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3582 |                 fan4pin = !(sio_data->inb(sio_data, 0x2A) & 0x80);
         |                             ~~~~~~~~~~~~~                 ^
         |                                     |
         |                                     int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3584:57: error: macro "inb" passed 2 arguments, but takes just 1
    3584 |                 bool gpok = sio_data->inb(sio_data, 0x27) & 0x80;
         |                                                         ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3584:59: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3584 |                 bool gpok = sio_data->inb(sio_data, 0x27) & 0x80;
         |                             ~~~~~~~~~~~~~                 ^
         |                                     |
         |                                     int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3601:74: error: macro "outb" passed 3 arguments, but takes just 2
    3601 |                                                      data->sio_reg_enable);
         |                                                                          ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:3600:49: warning: statement with no effect [-Wunused-value]
    3600 |                                         sio_data->outb(sio_data, SIO_REG_ENABLE,
         |                                         ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c:3609:65: error: macro "inb" passed 2 arguments, but takes just 1
    3609 |                         fan3pin = !(sio_data->inb(sio_data, 0x24) & 0x40);
         |                                                                 ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3609:67: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3609 |                         fan3pin = !(sio_data->inb(sio_data, 0x24) & 0x40);
         |                                     ~~~~~~~~~~~~~                 ^
         |                                             |
         |                                             int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3614:63: error: macro "inb" passed 2 arguments, but takes just 1
    3614 |                         fan4pin = sio_data->inb(sio_data, 0x1C) & 0x01;
         |                                                               ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3614:65: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3614 |                         fan4pin = sio_data->inb(sio_data, 0x1C) & 0x01;
         |                                   ~~~~~~~~~~~~~                 ^
         |                                           |
         |                                           int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3619:63: error: macro "inb" passed 2 arguments, but takes just 1
    3619 |                         fan5pin = sio_data->inb(sio_data, 0x1C) & 0x02;
         |                                                               ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3619:65: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3619 |                         fan5pin = sio_data->inb(sio_data, 0x1C) & 0x02;
         |                                   ~~~~~~~~~~~~~                 ^
         |                                           |
         |                                           int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3624:56: error: macro "inb" passed 2 arguments, but takes just 1
    3624 |                 int cr24 = sio_data->inb(sio_data, 0x24);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3624:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3624 |                 int cr24 = sio_data->inb(sio_data, 0x24);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3629:56: error: macro "inb" passed 2 arguments, but takes just 1
    3629 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3629:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3629 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3630:56: error: macro "inb" passed 2 arguments, but takes just 1
    3630 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3630:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3630 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                            ^~~~~~~~
--
         | 
   drivers/hwmon/nct6775.c:3634:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3634 |                 int cr2f = sio_data->inb(sio_data, 0x2f);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3650:56: error: macro "inb" passed 2 arguments, but takes just 1
    3650 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3650:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3650 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3651:56: error: macro "inb" passed 2 arguments, but takes just 1
    3651 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3651:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3651 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3652:56: error: macro "inb" passed 2 arguments, but takes just 1
    3652 |                 int cr1c = sio_data->inb(sio_data, 0x1c);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3652:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3652 |                 int cr1c = sio_data->inb(sio_data, 0x1c);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3653:56: error: macro "inb" passed 2 arguments, but takes just 1
    3653 |                 int cr1d = sio_data->inb(sio_data, 0x1d);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3653:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3653 |                 int cr1d = sio_data->inb(sio_data, 0x1d);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3654:56: error: macro "inb" passed 2 arguments, but takes just 1
    3654 |                 int cr2a = sio_data->inb(sio_data, 0x2a);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3654:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3654 |                 int cr2a = sio_data->inb(sio_data, 0x2a);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3655:56: error: macro "inb" passed 2 arguments, but takes just 1
    3655 |                 int cr2b = sio_data->inb(sio_data, 0x2b);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3655:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3655 |                 int cr2b = sio_data->inb(sio_data, 0x2b);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3656:56: error: macro "inb" passed 2 arguments, but takes just 1
    3656 |                 int cr2d = sio_data->inb(sio_data, 0x2d);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3656:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3656 |                 int cr2d = sio_data->inb(sio_data, 0x2d);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3657:56: error: macro "inb" passed 2 arguments, but takes just 1
    3657 |                 int cr2f = sio_data->inb(sio_data, 0x2f);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3657:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3657 |                 int cr2f = sio_data->inb(sio_data, 0x2f);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3665:52: error: macro "inb" passed 2 arguments, but takes just 1
    3665 |                 cre0 = sio_data->inb(sio_data, 0xe0);
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3665:22: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3665 |                 cre0 = sio_data->inb(sio_data, 0xe0);
         |                      ^
   drivers/hwmon/nct6775.c:3666:52: error: macro "inb" passed 2 arguments, but takes just 1
    3666 |                 creb = sio_data->inb(sio_data, 0xeb);
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3666:22: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3666 |                 creb = sio_data->inb(sio_data, 0xeb);
         |                      ^
   drivers/hwmon/nct6775.c:3667:52: error: macro "inb" passed 2 arguments, but takes just 1
    3667 |                 cred = sio_data->inb(sio_data, 0xed);
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3667:22: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3667 |                 cred = sio_data->inb(sio_data, 0xed);
         |                      ^
   drivers/hwmon/nct6775.c: In function 'nct6775_probe':
   drivers/hwmon/nct6775.c:4531:44: error: macro "inb" passed 2 arguments, but takes just 1
    4531 |         cr2a = sio_data->inb(sio_data, 0x2a);
         |                                            ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4531:14: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4531 |         cr2a = sio_data->inb(sio_data, 0x2a);
         |              ^
   drivers/hwmon/nct6775.c:4558:57: error: macro "inb" passed 2 arguments, but takes just 1
    4558 |                 data->vid = sio_data->inb(sio_data, 0xe3);
         |                                                         ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4558:27: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4558 |                 data->vid = sio_data->inb(sio_data, 0xe3);
         |                           ^
   drivers/hwmon/nct6775.c:4567:64: error: macro "inb" passed 2 arguments, but takes just 1
    4567 |                                     NCT6775_REG_CR_FAN_DEBOUNCE);
         |                                                                ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4566:21: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4566 |                 tmp = sio_data->inb(sio_data,
         |                     ^
   drivers/hwmon/nct6775.c:4591:33: error: macro "outb" passed 3 arguments, but takes just 2
    4591 |                              tmp);
         |                                 ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4590:25: warning: statement with no effect [-Wunused-value]
    4590 |                 sio_data->outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE,
         |                 ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6791_enable_io_mapping':
   drivers/hwmon/nct6775.c:4642:74: error: macro "inb" passed 2 arguments, but takes just 1
    4642 |         val = sio_data->inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
         |                                                                          ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4642:13: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4642 |         val = sio_data->inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
         |             ^
   drivers/hwmon/nct6775.c:4646:43: error: macro "outb" passed 3 arguments, but takes just 2
    4646 |                                val & ~0x10);
         |                                           ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4645:25: warning: statement with no effect [-Wunused-value]
    4645 |                 sio_data->outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
         |                 ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6775_resume':
   drivers/hwmon/nct6775.c:4680:53: error: macro "inb" passed 2 arguments, but takes just 1
    4680 |         reg = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                                                     ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4680:13: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4680 |         reg = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |             ^
   drivers/hwmon/nct6775.c:4682:78: error: macro "outb" passed 3 arguments, but takes just 2
    4682 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
         |                                                                              ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4682:25: warning: statement with no effect [-Wunused-value]
    4682 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
         |                 ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6775_find':
   drivers/hwmon/nct6775.c:4759:53: error: macro "inb" passed 2 arguments, but takes just 1
    4759 |         val = (sio_data->inb(sio_data, SIO_REG_DEVID) << 8) |
         |                                                     ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4759:55: error: invalid operands to binary << (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    4759 |         val = (sio_data->inb(sio_data, SIO_REG_DEVID) << 8) |
         |                ~~~~~~~~~~~~~                          ^~
         |                        |
         |                        int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:4760:58: error: macro "inb" passed 2 arguments, but takes just 1
    4760 |                 sio_data->inb(sio_data, SIO_REG_DEVID + 1);
         |                                                          ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4810:52: error: macro "inb" passed 2 arguments, but takes just 1
    4810 |         val = (sio_data->inb(sio_data, SIO_REG_ADDR) << 8)
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4810:54: error: invalid operands to binary << (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    4810 |         val = (sio_data->inb(sio_data, SIO_REG_ADDR) << 8)
         |                ~~~~~~~~~~~~~                         ^~
         |                        |
         |                        int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:4811:55: error: macro "inb" passed 2 arguments, but takes just 1
    4811 |             | sio_data->inb(sio_data, SIO_REG_ADDR + 1);
         |                                                       ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4820:53: error: macro "inb" passed 2 arguments, but takes just 1
    4820 |         val = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                                                     ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:4820:13: warning: assignment to 'u16' {aka 'short unsigned int'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4820 |         val = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |             ^
   drivers/hwmon/nct6775.c:4823:68: error: macro "outb" passed 3 arguments, but takes just 2
    4823 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, val | 0x01);
         |                                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4823:25: warning: statement with no effect [-Wunused-value]
    4823 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, val | 0x01);
         |                 ~~~~~~~~^~~~~~
   At top level:
   drivers/hwmon/nct6775.c:284:17: warning: 'NCT6775_REG_CR_CASEOPEN_CLR' defined but not used [-Wunused-const-variable=]
     284 | static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/inb +3452 drivers/hwmon/nct6775.c

  3423	
  3424	static ssize_t
  3425	clear_caseopen(struct device *dev, struct device_attribute *attr,
  3426		       const char *buf, size_t count)
  3427	{
  3428		struct nct6775_data *data = dev_get_drvdata(dev);
  3429		struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
  3430		int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
  3431		unsigned long val;
  3432		u8 reg;
  3433		int ret;
  3434	
  3435		if (kstrtoul(buf, 10, &val) || val != 0)
  3436			return -EINVAL;
  3437	
  3438		mutex_lock(&data->update_lock);
  3439	
  3440		/*
  3441		 * Use CR registers to clear caseopen status.
  3442		 * The CR registers are the same for all chips, and not all chips
  3443		 * support clearing the caseopen status through "regular" registers.
  3444		 */
  3445		ret = sio_data->enter(sio_data);
  3446		if (ret) {
  3447			count = ret;
  3448			goto error;
  3449		}
  3450	
  3451		sio_data->select(sio_data, NCT6775_LD_ACPI);
> 3452		reg = sio_data->inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
  3453		reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
> 3454		sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
  3455		reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
  3456		sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
  3457		sio_data->exit(sio_data);
  3458	
  3459		data->valid = false;	/* Force cache refresh */
  3460	error:
  3461		mutex_unlock(&data->update_lock);
  3462		return count;
  3463	}
  3464	
  3465	static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
  3466				  clear_caseopen, INTRUSION_ALARM_BASE);
  3467	static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
  3468				  clear_caseopen, INTRUSION_ALARM_BASE + 1);
  3469	static SENSOR_DEVICE_ATTR(intrusion0_beep, S_IWUSR | S_IRUGO, show_beep,
  3470				  store_beep, INTRUSION_ALARM_BASE);
  3471	static SENSOR_DEVICE_ATTR(intrusion1_beep, S_IWUSR | S_IRUGO, show_beep,
  3472				  store_beep, INTRUSION_ALARM_BASE + 1);
  3473	static SENSOR_DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_beep,
  3474				  store_beep, BEEP_ENABLE_BASE);
  3475	
  3476	static umode_t nct6775_other_is_visible(struct kobject *kobj,
  3477						struct attribute *attr, int index)
  3478	{
  3479		struct device *dev = kobj_to_dev(kobj);
  3480		struct nct6775_data *data = dev_get_drvdata(dev);
  3481	
  3482		if (index == 0 && !data->have_vid)
  3483			return 0;
  3484	
  3485		if (index == 1 || index == 2) {
  3486			if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
  3487				return 0;
  3488		}
  3489	
  3490		if (index == 3 || index == 4) {
  3491			if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
  3492				return 0;
  3493		}
  3494	
  3495		return attr->mode;
  3496	}
  3497	
  3498	/*
  3499	 * nct6775_other_is_visible uses the index into the following array
  3500	 * to determine if attributes should be created or not.
  3501	 * Any change in order or content must be matched.
  3502	 */
  3503	static struct attribute *nct6775_attributes_other[] = {
  3504		&dev_attr_cpu0_vid.attr,				/* 0 */
  3505		&sensor_dev_attr_intrusion0_alarm.dev_attr.attr,	/* 1 */
  3506		&sensor_dev_attr_intrusion1_alarm.dev_attr.attr,	/* 2 */
  3507		&sensor_dev_attr_intrusion0_beep.dev_attr.attr,		/* 3 */
  3508		&sensor_dev_attr_intrusion1_beep.dev_attr.attr,		/* 4 */
  3509		&sensor_dev_attr_beep_enable.dev_attr.attr,		/* 5 */
  3510	
  3511		NULL
  3512	};
  3513	
  3514	static const struct attribute_group nct6775_group_other = {
  3515		.attrs = nct6775_attributes_other,
  3516		.is_visible = nct6775_other_is_visible,
  3517	};
  3518	
  3519	static inline void nct6775_init_device(struct nct6775_data *data)
  3520	{
  3521		int i;
  3522		u8 tmp, diode;
  3523	
  3524		/* Start monitoring if needed */
  3525		if (data->REG_CONFIG) {
  3526			tmp = data->read_value(data, data->REG_CONFIG);
  3527			if (!(tmp & 0x01))
  3528				data->write_value(data, data->REG_CONFIG, tmp | 0x01);
  3529		}
  3530	
  3531		/* Enable temperature sensors if needed */
  3532		for (i = 0; i < NUM_TEMP; i++) {
  3533			if (!(data->have_temp & BIT(i)))
  3534				continue;
  3535			if (!data->reg_temp_config[i])
  3536				continue;
  3537			tmp = data->read_value(data, data->reg_temp_config[i]);
  3538			if (tmp & 0x01)
  3539				data->write_value(data, data->reg_temp_config[i],
  3540						    tmp & 0xfe);
  3541		}
  3542	
  3543		/* Enable VBAT monitoring if needed */
  3544		tmp = data->read_value(data, data->REG_VBAT);
  3545		if (!(tmp & 0x01))
  3546			data->write_value(data, data->REG_VBAT, tmp | 0x01);
  3547	
  3548		diode = data->read_value(data, data->REG_DIODE);
  3549	
  3550		for (i = 0; i < data->temp_fixed_num; i++) {
  3551			if (!(data->have_temp_fixed & BIT(i)))
  3552				continue;
  3553			if ((tmp & (data->DIODE_MASK << i)))	/* diode */
  3554				data->temp_type[i]
  3555				  = 3 - ((diode >> i) & data->DIODE_MASK);
  3556			else				/* thermistor */
  3557				data->temp_type[i] = 4;
  3558		}
  3559	}
  3560	
  3561	static void
  3562	nct6775_check_fan_inputs(struct nct6775_data *data,
  3563			struct nct6775_sio_data *sio_data)
  3564	{
  3565		bool fan3pin = false, fan4pin = false, fan4min = false;
  3566		bool fan5pin = false, fan6pin = false, fan7pin = false;
  3567		bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
  3568		bool pwm6pin = false, pwm7pin = false;
  3569	
  3570		/* Store SIO_REG_ENABLE for use during resume */
  3571		sio_data->select(sio_data, NCT6775_LD_HWM);
  3572		data->sio_reg_enable = sio_data->inb(sio_data, SIO_REG_ENABLE);
  3573	
  3574		/* fan4 and fan5 share some pins with the GPIO and serial flash */
  3575		if (data->kind == nct6775) {
> 3576			int cr2c = sio_data->inb(sio_data, 0x2c);
  3577	
  3578			fan3pin = cr2c & BIT(6);
  3579			pwm3pin = cr2c & BIT(7);
  3580	
  3581			/* On NCT6775, fan4 shares pins with the fdc interface */
> 3582			fan4pin = !(sio_data->inb(sio_data, 0x2A) & 0x80);
  3583		} else if (data->kind == nct6776) {
  3584			bool gpok = sio_data->inb(sio_data, 0x27) & 0x80;
  3585			const char *board_vendor, *board_name;
  3586	
  3587			board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
  3588			board_name = dmi_get_system_info(DMI_BOARD_NAME);
  3589	
  3590			if (board_name && board_vendor &&
  3591			    !strcmp(board_vendor, "ASRock")) {
  3592				/*
  3593				 * Auxiliary fan monitoring is not enabled on ASRock
  3594				 * Z77 Pro4-M if booted in UEFI Ultra-FastBoot mode.
  3595				 * Observed with BIOS version 2.00.
  3596				 */
  3597				if (!strcmp(board_name, "Z77 Pro4-M")) {
  3598					if ((data->sio_reg_enable & 0xe0) != 0xe0) {
  3599						data->sio_reg_enable |= 0xe0;
  3600						sio_data->outb(sio_data, SIO_REG_ENABLE,
  3601							     data->sio_reg_enable);
  3602					}
  3603				}
  3604			}
  3605	
  3606			if (data->sio_reg_enable & 0x80)
  3607				fan3pin = gpok;
  3608			else
  3609				fan3pin = !(sio_data->inb(sio_data, 0x24) & 0x40);
  3610	
  3611			if (data->sio_reg_enable & 0x40)
  3612				fan4pin = gpok;
  3613			else
  3614				fan4pin = sio_data->inb(sio_data, 0x1C) & 0x01;
  3615	
  3616			if (data->sio_reg_enable & 0x20)
  3617				fan5pin = gpok;
  3618			else
  3619				fan5pin = sio_data->inb(sio_data, 0x1C) & 0x02;
  3620	
  3621			fan4min = fan4pin;
  3622			pwm3pin = fan3pin;
  3623		} else if (data->kind == nct6106) {
  3624			int cr24 = sio_data->inb(sio_data, 0x24);
  3625	
  3626			fan3pin = !(cr24 & 0x80);
  3627			pwm3pin = cr24 & 0x08;
  3628		} else if (data->kind == nct6116) {
  3629			int cr1a = sio_data->inb(sio_data, 0x1a);
  3630			int cr1b = sio_data->inb(sio_data, 0x1b);
  3631			int cr24 = sio_data->inb(sio_data, 0x24);
  3632			int cr2a = sio_data->inb(sio_data, 0x2a);
  3633			int cr2b = sio_data->inb(sio_data, 0x2b);
  3634			int cr2f = sio_data->inb(sio_data, 0x2f);
  3635	
  3636			fan3pin = !(cr2b & 0x10);
  3637			fan4pin = (cr2b & 0x80) ||			// pin 1(2)
  3638				(!(cr2f & 0x10) && (cr1a & 0x04));	// pin 65(66)
  3639			fan5pin = (cr2b & 0x80) ||			// pin 126(127)
  3640				(!(cr1b & 0x03) && (cr2a & 0x02));	// pin 94(96)
  3641	
  3642			pwm3pin = fan3pin && (cr24 & 0x08);
  3643			pwm4pin = fan4pin;
  3644			pwm5pin = fan5pin;
  3645		} else {
  3646			/*
  3647			 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
  3648			 * NCT6797D, NCT6798D
  3649			 */
  3650			int cr1a = sio_data->inb(sio_data, 0x1a);
  3651			int cr1b = sio_data->inb(sio_data, 0x1b);
  3652			int cr1c = sio_data->inb(sio_data, 0x1c);
  3653			int cr1d = sio_data->inb(sio_data, 0x1d);
  3654			int cr2a = sio_data->inb(sio_data, 0x2a);
  3655			int cr2b = sio_data->inb(sio_data, 0x2b);
  3656			int cr2d = sio_data->inb(sio_data, 0x2d);
  3657			int cr2f = sio_data->inb(sio_data, 0x2f);
  3658			bool dsw_en = cr2f & BIT(3);
  3659			bool ddr4_en = cr2f & BIT(4);
  3660			int cre0;
  3661			int creb;
  3662			int cred;
  3663	
  3664			sio_data->select(sio_data, NCT6775_LD_12);
  3665			cre0 = sio_data->inb(sio_data, 0xe0);
  3666			creb = sio_data->inb(sio_data, 0xeb);
  3667			cred = sio_data->inb(sio_data, 0xed);
  3668	
  3669			fan3pin = !(cr1c & BIT(5));
  3670			fan4pin = !(cr1c & BIT(6));
  3671			fan5pin = !(cr1c & BIT(7));
  3672	
  3673			pwm3pin = !(cr1c & BIT(0));
  3674			pwm4pin = !(cr1c & BIT(1));
  3675			pwm5pin = !(cr1c & BIT(2));
  3676	
  3677			switch (data->kind) {
  3678			case nct6791:
  3679				fan6pin = cr2d & BIT(1);
  3680				pwm6pin = cr2d & BIT(0);
  3681				break;
  3682			case nct6792:
  3683				fan6pin = !dsw_en && (cr2d & BIT(1));
  3684				pwm6pin = !dsw_en && (cr2d & BIT(0));
  3685				break;
  3686			case nct6793:
  3687				fan5pin |= cr1b & BIT(5);
  3688				fan5pin |= creb & BIT(5);
  3689	
  3690				fan6pin = !dsw_en && (cr2d & BIT(1));
  3691				fan6pin |= creb & BIT(3);
  3692	
  3693				pwm5pin |= cr2d & BIT(7);
  3694				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3695	
  3696				pwm6pin = !dsw_en && (cr2d & BIT(0));
  3697				pwm6pin |= creb & BIT(2);
  3698				break;
  3699			case nct6795:
  3700				fan5pin |= cr1b & BIT(5);
  3701				fan5pin |= creb & BIT(5);
  3702	
  3703				fan6pin = (cr2a & BIT(4)) &&
  3704						(!dsw_en || (cred & BIT(4)));
  3705				fan6pin |= creb & BIT(3);
  3706	
  3707				pwm5pin |= cr2d & BIT(7);
  3708				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3709	
  3710				pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
  3711				pwm6pin |= creb & BIT(2);
  3712				break;
  3713			case nct6796:
  3714				fan5pin |= cr1b & BIT(5);
  3715				fan5pin |= (cre0 & BIT(3)) && !(cr1b & BIT(0));
  3716				fan5pin |= creb & BIT(5);
  3717	
  3718				fan6pin = (cr2a & BIT(4)) &&
  3719						(!dsw_en || (cred & BIT(4)));
  3720				fan6pin |= creb & BIT(3);
  3721	
  3722				fan7pin = !(cr2b & BIT(2));
  3723	
  3724				pwm5pin |= cr2d & BIT(7);
  3725				pwm5pin |= (cre0 & BIT(4)) && !(cr1b & BIT(0));
  3726				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3727	
  3728				pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
  3729				pwm6pin |= creb & BIT(2);
  3730	
  3731				pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
  3732				break;
  3733			case nct6797:
  3734				fan5pin |= !ddr4_en && (cr1b & BIT(5));
  3735				fan5pin |= creb & BIT(5);
  3736	
  3737				fan6pin = cr2a & BIT(4);
  3738				fan6pin |= creb & BIT(3);
  3739	
  3740				fan7pin = cr1a & BIT(1);
  3741	
  3742				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3743				pwm5pin |= !ddr4_en && (cr2d & BIT(7));
  3744	
  3745				pwm6pin = creb & BIT(2);
  3746				pwm6pin |= cred & BIT(2);
  3747	
  3748				pwm7pin = cr1d & BIT(4);
  3749				break;
  3750			case nct6798:
  3751				fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
  3752				fan6pin |= cr2a & BIT(4);
  3753				fan6pin |= creb & BIT(5);
  3754	
  3755				fan7pin = cr1b & BIT(5);
  3756				fan7pin |= !(cr2b & BIT(2));
  3757				fan7pin |= creb & BIT(3);
  3758	
  3759				pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
  3760				pwm6pin |= !(cred & BIT(2)) && (cr2a & BIT(3));
  3761				pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3762	
  3763				pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
  3764				pwm7pin |= cr2d & BIT(7);
  3765				pwm7pin |= creb & BIT(2);
  3766				break;
  3767			default:	/* NCT6779D */
  3768				break;
  3769			}
  3770	
  3771			fan4min = fan4pin;
  3772		}
  3773	
  3774		/* fan 1 and 2 (0x03) are always present */
  3775		data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
  3776			(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
  3777		data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
  3778			(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
  3779		data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
  3780			(pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
  3781	}
  3782	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35738 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*().
@ 2021-09-12 14:50     ` kernel test robot
  0 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-09-12 14:50 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 46706 bytes --]

Hi Denis,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hwmon/hwmon-next]
[also build test ERROR on v5.14 next-20210910]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Denis-Pauk/hwmon-nct6775-Support-access-via-Asus-WMI/20210912-190749
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: arm-randconfig-s032-20210912 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/f11f2179ea7eb747b68a65ac03fce15ff4319004
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Denis-Pauk/hwmon-nct6775-Support-access-via-Asus-WMI/20210912-190749
        git checkout f11f2179ea7eb747b68a65ac03fce15ff4319004
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arm SHELL=/bin/bash drivers/hwmon/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   drivers/hwmon/nct6775.c: In function 'clear_caseopen':
>> drivers/hwmon/nct6775.c:3452:70: error: macro "inb" passed 2 arguments, but takes just 1
    3452 |         reg = sio_data->inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3452:13: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3452 |         reg = sio_data->inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
         |             ^
>> drivers/hwmon/nct6775.c:3454:70: error: macro "outb" passed 3 arguments, but takes just 2
    3454 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:3454:17: warning: statement with no effect [-Wunused-value]
    3454 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |         ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c:3456:70: error: macro "outb" passed 3 arguments, but takes just 2
    3456 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:3456:17: warning: statement with no effect [-Wunused-value]
    3456 |         sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
         |         ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6775_check_fan_inputs':
   drivers/hwmon/nct6775.c:3572:70: error: macro "inb" passed 2 arguments, but takes just 1
    3572 |         data->sio_reg_enable = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                                                                      ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3572:30: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3572 |         data->sio_reg_enable = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                              ^
   drivers/hwmon/nct6775.c:3576:56: error: macro "inb" passed 2 arguments, but takes just 1
    3576 |                 int cr2c = sio_data->inb(sio_data, 0x2c);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3576:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3576 |                 int cr2c = sio_data->inb(sio_data, 0x2c);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3582:57: error: macro "inb" passed 2 arguments, but takes just 1
    3582 |                 fan4pin = !(sio_data->inb(sio_data, 0x2A) & 0x80);
         |                                                         ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3582:59: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3582 |                 fan4pin = !(sio_data->inb(sio_data, 0x2A) & 0x80);
         |                             ~~~~~~~~~~~~~                 ^
         |                                     |
         |                                     int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3584:57: error: macro "inb" passed 2 arguments, but takes just 1
    3584 |                 bool gpok = sio_data->inb(sio_data, 0x27) & 0x80;
         |                                                         ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3584:59: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3584 |                 bool gpok = sio_data->inb(sio_data, 0x27) & 0x80;
         |                             ~~~~~~~~~~~~~                 ^
         |                                     |
         |                                     int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3601:74: error: macro "outb" passed 3 arguments, but takes just 2
    3601 |                                                      data->sio_reg_enable);
         |                                                                          ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:3600:49: warning: statement with no effect [-Wunused-value]
    3600 |                                         sio_data->outb(sio_data, SIO_REG_ENABLE,
         |                                         ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c:3609:65: error: macro "inb" passed 2 arguments, but takes just 1
    3609 |                         fan3pin = !(sio_data->inb(sio_data, 0x24) & 0x40);
         |                                                                 ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3609:67: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3609 |                         fan3pin = !(sio_data->inb(sio_data, 0x24) & 0x40);
         |                                     ~~~~~~~~~~~~~                 ^
         |                                             |
         |                                             int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3614:63: error: macro "inb" passed 2 arguments, but takes just 1
    3614 |                         fan4pin = sio_data->inb(sio_data, 0x1C) & 0x01;
         |                                                               ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3614:65: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3614 |                         fan4pin = sio_data->inb(sio_data, 0x1C) & 0x01;
         |                                   ~~~~~~~~~~~~~                 ^
         |                                           |
         |                                           int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3619:63: error: macro "inb" passed 2 arguments, but takes just 1
    3619 |                         fan5pin = sio_data->inb(sio_data, 0x1C) & 0x02;
         |                                                               ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3619:65: error: invalid operands to binary & (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    3619 |                         fan5pin = sio_data->inb(sio_data, 0x1C) & 0x02;
         |                                   ~~~~~~~~~~~~~                 ^
         |                                           |
         |                                           int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:3624:56: error: macro "inb" passed 2 arguments, but takes just 1
    3624 |                 int cr24 = sio_data->inb(sio_data, 0x24);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3624:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3624 |                 int cr24 = sio_data->inb(sio_data, 0x24);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3629:56: error: macro "inb" passed 2 arguments, but takes just 1
    3629 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3629:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3629 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3630:56: error: macro "inb" passed 2 arguments, but takes just 1
    3630 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3630:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3630 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                            ^~~~~~~~
--
         | 
   drivers/hwmon/nct6775.c:3634:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3634 |                 int cr2f = sio_data->inb(sio_data, 0x2f);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3650:56: error: macro "inb" passed 2 arguments, but takes just 1
    3650 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3650:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3650 |                 int cr1a = sio_data->inb(sio_data, 0x1a);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3651:56: error: macro "inb" passed 2 arguments, but takes just 1
    3651 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3651:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3651 |                 int cr1b = sio_data->inb(sio_data, 0x1b);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3652:56: error: macro "inb" passed 2 arguments, but takes just 1
    3652 |                 int cr1c = sio_data->inb(sio_data, 0x1c);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3652:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3652 |                 int cr1c = sio_data->inb(sio_data, 0x1c);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3653:56: error: macro "inb" passed 2 arguments, but takes just 1
    3653 |                 int cr1d = sio_data->inb(sio_data, 0x1d);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3653:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3653 |                 int cr1d = sio_data->inb(sio_data, 0x1d);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3654:56: error: macro "inb" passed 2 arguments, but takes just 1
    3654 |                 int cr2a = sio_data->inb(sio_data, 0x2a);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3654:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3654 |                 int cr2a = sio_data->inb(sio_data, 0x2a);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3655:56: error: macro "inb" passed 2 arguments, but takes just 1
    3655 |                 int cr2b = sio_data->inb(sio_data, 0x2b);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3655:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3655 |                 int cr2b = sio_data->inb(sio_data, 0x2b);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3656:56: error: macro "inb" passed 2 arguments, but takes just 1
    3656 |                 int cr2d = sio_data->inb(sio_data, 0x2d);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3656:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3656 |                 int cr2d = sio_data->inb(sio_data, 0x2d);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3657:56: error: macro "inb" passed 2 arguments, but takes just 1
    3657 |                 int cr2f = sio_data->inb(sio_data, 0x2f);
         |                                                        ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3657:28: warning: initialization of 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3657 |                 int cr2f = sio_data->inb(sio_data, 0x2f);
         |                            ^~~~~~~~
   drivers/hwmon/nct6775.c:3665:52: error: macro "inb" passed 2 arguments, but takes just 1
    3665 |                 cre0 = sio_data->inb(sio_data, 0xe0);
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:3665:22: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3665 |                 cre0 = sio_data->inb(sio_data, 0xe0);
         |                      ^
   drivers/hwmon/nct6775.c:3666:52: error: macro "inb" passed 2 arguments, but takes just 1
    3666 |                 creb = sio_data->inb(sio_data, 0xeb);
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3666:22: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3666 |                 creb = sio_data->inb(sio_data, 0xeb);
         |                      ^
   drivers/hwmon/nct6775.c:3667:52: error: macro "inb" passed 2 arguments, but takes just 1
    3667 |                 cred = sio_data->inb(sio_data, 0xed);
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:3667:22: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    3667 |                 cred = sio_data->inb(sio_data, 0xed);
         |                      ^
   drivers/hwmon/nct6775.c: In function 'nct6775_probe':
   drivers/hwmon/nct6775.c:4531:44: error: macro "inb" passed 2 arguments, but takes just 1
    4531 |         cr2a = sio_data->inb(sio_data, 0x2a);
         |                                            ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4531:14: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4531 |         cr2a = sio_data->inb(sio_data, 0x2a);
         |              ^
   drivers/hwmon/nct6775.c:4558:57: error: macro "inb" passed 2 arguments, but takes just 1
    4558 |                 data->vid = sio_data->inb(sio_data, 0xe3);
         |                                                         ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4558:27: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4558 |                 data->vid = sio_data->inb(sio_data, 0xe3);
         |                           ^
   drivers/hwmon/nct6775.c:4567:64: error: macro "inb" passed 2 arguments, but takes just 1
    4567 |                                     NCT6775_REG_CR_FAN_DEBOUNCE);
         |                                                                ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4566:21: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4566 |                 tmp = sio_data->inb(sio_data,
         |                     ^
   drivers/hwmon/nct6775.c:4591:33: error: macro "outb" passed 3 arguments, but takes just 2
    4591 |                              tmp);
         |                                 ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4590:25: warning: statement with no effect [-Wunused-value]
    4590 |                 sio_data->outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE,
         |                 ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6791_enable_io_mapping':
   drivers/hwmon/nct6775.c:4642:74: error: macro "inb" passed 2 arguments, but takes just 1
    4642 |         val = sio_data->inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
         |                                                                          ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4642:13: warning: assignment to 'int' from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4642 |         val = sio_data->inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
         |             ^
   drivers/hwmon/nct6775.c:4646:43: error: macro "outb" passed 3 arguments, but takes just 2
    4646 |                                val & ~0x10);
         |                                           ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4645:25: warning: statement with no effect [-Wunused-value]
    4645 |                 sio_data->outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
         |                 ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6775_resume':
   drivers/hwmon/nct6775.c:4680:53: error: macro "inb" passed 2 arguments, but takes just 1
    4680 |         reg = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                                                     ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4680:13: warning: assignment to 'u8' {aka 'unsigned char'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4680 |         reg = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |             ^
   drivers/hwmon/nct6775.c:4682:78: error: macro "outb" passed 3 arguments, but takes just 2
    4682 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
         |                                                                              ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4682:25: warning: statement with no effect [-Wunused-value]
    4682 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
         |                 ~~~~~~~~^~~~~~
   drivers/hwmon/nct6775.c: In function 'nct6775_find':
   drivers/hwmon/nct6775.c:4759:53: error: macro "inb" passed 2 arguments, but takes just 1
    4759 |         val = (sio_data->inb(sio_data, SIO_REG_DEVID) << 8) |
         |                                                     ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4759:55: error: invalid operands to binary << (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    4759 |         val = (sio_data->inb(sio_data, SIO_REG_DEVID) << 8) |
         |                ~~~~~~~~~~~~~                          ^~
         |                        |
         |                        int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:4760:58: error: macro "inb" passed 2 arguments, but takes just 1
    4760 |                 sio_data->inb(sio_data, SIO_REG_DEVID + 1);
         |                                                          ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4810:52: error: macro "inb" passed 2 arguments, but takes just 1
    4810 |         val = (sio_data->inb(sio_data, SIO_REG_ADDR) << 8)
         |                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4810:54: error: invalid operands to binary << (have 'int (*)(struct nct6775_sio_data *, int)' and 'int')
    4810 |         val = (sio_data->inb(sio_data, SIO_REG_ADDR) << 8)
         |                ~~~~~~~~~~~~~                         ^~
         |                        |
         |                        int (*)(struct nct6775_sio_data *, int)
   drivers/hwmon/nct6775.c:4811:55: error: macro "inb" passed 2 arguments, but takes just 1
    4811 |             | sio_data->inb(sio_data, SIO_REG_ADDR + 1);
         |                                                       ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
   drivers/hwmon/nct6775.c:4820:53: error: macro "inb" passed 2 arguments, but takes just 1
    4820 |         val = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |                                                     ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:258: note: macro "inb" defined here
     258 | #define inb(p)  ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
         | 
>> drivers/hwmon/nct6775.c:4820:13: warning: assignment to 'u16' {aka 'short unsigned int'} from 'int (*)(struct nct6775_sio_data *, int)' makes integer from pointer without a cast [-Wint-conversion]
    4820 |         val = sio_data->inb(sio_data, SIO_REG_ENABLE);
         |             ^
   drivers/hwmon/nct6775.c:4823:68: error: macro "outb" passed 3 arguments, but takes just 2
    4823 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, val | 0x01);
         |                                                                    ^
   In file included from include/linux/io.h:13,
                    from drivers/hwmon/nct6775.c:56:
   arch/arm/include/asm/io.h:252: note: macro "outb" defined here
     252 | #define outb(v,p)       ({ __iowmb(); __raw_writeb(v,__io(p)); })
         | 
   drivers/hwmon/nct6775.c:4823:25: warning: statement with no effect [-Wunused-value]
    4823 |                 sio_data->outb(sio_data, SIO_REG_ENABLE, val | 0x01);
         |                 ~~~~~~~~^~~~~~
   At top level:
   drivers/hwmon/nct6775.c:284:17: warning: 'NCT6775_REG_CR_CASEOPEN_CLR' defined but not used [-Wunused-const-variable=]
     284 | static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/inb +3452 drivers/hwmon/nct6775.c

  3423	
  3424	static ssize_t
  3425	clear_caseopen(struct device *dev, struct device_attribute *attr,
  3426		       const char *buf, size_t count)
  3427	{
  3428		struct nct6775_data *data = dev_get_drvdata(dev);
  3429		struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
  3430		int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
  3431		unsigned long val;
  3432		u8 reg;
  3433		int ret;
  3434	
  3435		if (kstrtoul(buf, 10, &val) || val != 0)
  3436			return -EINVAL;
  3437	
  3438		mutex_lock(&data->update_lock);
  3439	
  3440		/*
  3441		 * Use CR registers to clear caseopen status.
  3442		 * The CR registers are the same for all chips, and not all chips
  3443		 * support clearing the caseopen status through "regular" registers.
  3444		 */
  3445		ret = sio_data->enter(sio_data);
  3446		if (ret) {
  3447			count = ret;
  3448			goto error;
  3449		}
  3450	
  3451		sio_data->select(sio_data, NCT6775_LD_ACPI);
> 3452		reg = sio_data->inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
  3453		reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
> 3454		sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
  3455		reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
  3456		sio_data->outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
  3457		sio_data->exit(sio_data);
  3458	
  3459		data->valid = false;	/* Force cache refresh */
  3460	error:
  3461		mutex_unlock(&data->update_lock);
  3462		return count;
  3463	}
  3464	
  3465	static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
  3466				  clear_caseopen, INTRUSION_ALARM_BASE);
  3467	static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
  3468				  clear_caseopen, INTRUSION_ALARM_BASE + 1);
  3469	static SENSOR_DEVICE_ATTR(intrusion0_beep, S_IWUSR | S_IRUGO, show_beep,
  3470				  store_beep, INTRUSION_ALARM_BASE);
  3471	static SENSOR_DEVICE_ATTR(intrusion1_beep, S_IWUSR | S_IRUGO, show_beep,
  3472				  store_beep, INTRUSION_ALARM_BASE + 1);
  3473	static SENSOR_DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_beep,
  3474				  store_beep, BEEP_ENABLE_BASE);
  3475	
  3476	static umode_t nct6775_other_is_visible(struct kobject *kobj,
  3477						struct attribute *attr, int index)
  3478	{
  3479		struct device *dev = kobj_to_dev(kobj);
  3480		struct nct6775_data *data = dev_get_drvdata(dev);
  3481	
  3482		if (index == 0 && !data->have_vid)
  3483			return 0;
  3484	
  3485		if (index == 1 || index == 2) {
  3486			if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
  3487				return 0;
  3488		}
  3489	
  3490		if (index == 3 || index == 4) {
  3491			if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
  3492				return 0;
  3493		}
  3494	
  3495		return attr->mode;
  3496	}
  3497	
  3498	/*
  3499	 * nct6775_other_is_visible uses the index into the following array
  3500	 * to determine if attributes should be created or not.
  3501	 * Any change in order or content must be matched.
  3502	 */
  3503	static struct attribute *nct6775_attributes_other[] = {
  3504		&dev_attr_cpu0_vid.attr,				/* 0 */
  3505		&sensor_dev_attr_intrusion0_alarm.dev_attr.attr,	/* 1 */
  3506		&sensor_dev_attr_intrusion1_alarm.dev_attr.attr,	/* 2 */
  3507		&sensor_dev_attr_intrusion0_beep.dev_attr.attr,		/* 3 */
  3508		&sensor_dev_attr_intrusion1_beep.dev_attr.attr,		/* 4 */
  3509		&sensor_dev_attr_beep_enable.dev_attr.attr,		/* 5 */
  3510	
  3511		NULL
  3512	};
  3513	
  3514	static const struct attribute_group nct6775_group_other = {
  3515		.attrs = nct6775_attributes_other,
  3516		.is_visible = nct6775_other_is_visible,
  3517	};
  3518	
  3519	static inline void nct6775_init_device(struct nct6775_data *data)
  3520	{
  3521		int i;
  3522		u8 tmp, diode;
  3523	
  3524		/* Start monitoring if needed */
  3525		if (data->REG_CONFIG) {
  3526			tmp = data->read_value(data, data->REG_CONFIG);
  3527			if (!(tmp & 0x01))
  3528				data->write_value(data, data->REG_CONFIG, tmp | 0x01);
  3529		}
  3530	
  3531		/* Enable temperature sensors if needed */
  3532		for (i = 0; i < NUM_TEMP; i++) {
  3533			if (!(data->have_temp & BIT(i)))
  3534				continue;
  3535			if (!data->reg_temp_config[i])
  3536				continue;
  3537			tmp = data->read_value(data, data->reg_temp_config[i]);
  3538			if (tmp & 0x01)
  3539				data->write_value(data, data->reg_temp_config[i],
  3540						    tmp & 0xfe);
  3541		}
  3542	
  3543		/* Enable VBAT monitoring if needed */
  3544		tmp = data->read_value(data, data->REG_VBAT);
  3545		if (!(tmp & 0x01))
  3546			data->write_value(data, data->REG_VBAT, tmp | 0x01);
  3547	
  3548		diode = data->read_value(data, data->REG_DIODE);
  3549	
  3550		for (i = 0; i < data->temp_fixed_num; i++) {
  3551			if (!(data->have_temp_fixed & BIT(i)))
  3552				continue;
  3553			if ((tmp & (data->DIODE_MASK << i)))	/* diode */
  3554				data->temp_type[i]
  3555				  = 3 - ((diode >> i) & data->DIODE_MASK);
  3556			else				/* thermistor */
  3557				data->temp_type[i] = 4;
  3558		}
  3559	}
  3560	
  3561	static void
  3562	nct6775_check_fan_inputs(struct nct6775_data *data,
  3563			struct nct6775_sio_data *sio_data)
  3564	{
  3565		bool fan3pin = false, fan4pin = false, fan4min = false;
  3566		bool fan5pin = false, fan6pin = false, fan7pin = false;
  3567		bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
  3568		bool pwm6pin = false, pwm7pin = false;
  3569	
  3570		/* Store SIO_REG_ENABLE for use during resume */
  3571		sio_data->select(sio_data, NCT6775_LD_HWM);
  3572		data->sio_reg_enable = sio_data->inb(sio_data, SIO_REG_ENABLE);
  3573	
  3574		/* fan4 and fan5 share some pins with the GPIO and serial flash */
  3575		if (data->kind == nct6775) {
> 3576			int cr2c = sio_data->inb(sio_data, 0x2c);
  3577	
  3578			fan3pin = cr2c & BIT(6);
  3579			pwm3pin = cr2c & BIT(7);
  3580	
  3581			/* On NCT6775, fan4 shares pins with the fdc interface */
> 3582			fan4pin = !(sio_data->inb(sio_data, 0x2A) & 0x80);
  3583		} else if (data->kind == nct6776) {
  3584			bool gpok = sio_data->inb(sio_data, 0x27) & 0x80;
  3585			const char *board_vendor, *board_name;
  3586	
  3587			board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
  3588			board_name = dmi_get_system_info(DMI_BOARD_NAME);
  3589	
  3590			if (board_name && board_vendor &&
  3591			    !strcmp(board_vendor, "ASRock")) {
  3592				/*
  3593				 * Auxiliary fan monitoring is not enabled on ASRock
  3594				 * Z77 Pro4-M if booted in UEFI Ultra-FastBoot mode.
  3595				 * Observed with BIOS version 2.00.
  3596				 */
  3597				if (!strcmp(board_name, "Z77 Pro4-M")) {
  3598					if ((data->sio_reg_enable & 0xe0) != 0xe0) {
  3599						data->sio_reg_enable |= 0xe0;
  3600						sio_data->outb(sio_data, SIO_REG_ENABLE,
  3601							     data->sio_reg_enable);
  3602					}
  3603				}
  3604			}
  3605	
  3606			if (data->sio_reg_enable & 0x80)
  3607				fan3pin = gpok;
  3608			else
  3609				fan3pin = !(sio_data->inb(sio_data, 0x24) & 0x40);
  3610	
  3611			if (data->sio_reg_enable & 0x40)
  3612				fan4pin = gpok;
  3613			else
  3614				fan4pin = sio_data->inb(sio_data, 0x1C) & 0x01;
  3615	
  3616			if (data->sio_reg_enable & 0x20)
  3617				fan5pin = gpok;
  3618			else
  3619				fan5pin = sio_data->inb(sio_data, 0x1C) & 0x02;
  3620	
  3621			fan4min = fan4pin;
  3622			pwm3pin = fan3pin;
  3623		} else if (data->kind == nct6106) {
  3624			int cr24 = sio_data->inb(sio_data, 0x24);
  3625	
  3626			fan3pin = !(cr24 & 0x80);
  3627			pwm3pin = cr24 & 0x08;
  3628		} else if (data->kind == nct6116) {
  3629			int cr1a = sio_data->inb(sio_data, 0x1a);
  3630			int cr1b = sio_data->inb(sio_data, 0x1b);
  3631			int cr24 = sio_data->inb(sio_data, 0x24);
  3632			int cr2a = sio_data->inb(sio_data, 0x2a);
  3633			int cr2b = sio_data->inb(sio_data, 0x2b);
  3634			int cr2f = sio_data->inb(sio_data, 0x2f);
  3635	
  3636			fan3pin = !(cr2b & 0x10);
  3637			fan4pin = (cr2b & 0x80) ||			// pin 1(2)
  3638				(!(cr2f & 0x10) && (cr1a & 0x04));	// pin 65(66)
  3639			fan5pin = (cr2b & 0x80) ||			// pin 126(127)
  3640				(!(cr1b & 0x03) && (cr2a & 0x02));	// pin 94(96)
  3641	
  3642			pwm3pin = fan3pin && (cr24 & 0x08);
  3643			pwm4pin = fan4pin;
  3644			pwm5pin = fan5pin;
  3645		} else {
  3646			/*
  3647			 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
  3648			 * NCT6797D, NCT6798D
  3649			 */
  3650			int cr1a = sio_data->inb(sio_data, 0x1a);
  3651			int cr1b = sio_data->inb(sio_data, 0x1b);
  3652			int cr1c = sio_data->inb(sio_data, 0x1c);
  3653			int cr1d = sio_data->inb(sio_data, 0x1d);
  3654			int cr2a = sio_data->inb(sio_data, 0x2a);
  3655			int cr2b = sio_data->inb(sio_data, 0x2b);
  3656			int cr2d = sio_data->inb(sio_data, 0x2d);
  3657			int cr2f = sio_data->inb(sio_data, 0x2f);
  3658			bool dsw_en = cr2f & BIT(3);
  3659			bool ddr4_en = cr2f & BIT(4);
  3660			int cre0;
  3661			int creb;
  3662			int cred;
  3663	
  3664			sio_data->select(sio_data, NCT6775_LD_12);
  3665			cre0 = sio_data->inb(sio_data, 0xe0);
  3666			creb = sio_data->inb(sio_data, 0xeb);
  3667			cred = sio_data->inb(sio_data, 0xed);
  3668	
  3669			fan3pin = !(cr1c & BIT(5));
  3670			fan4pin = !(cr1c & BIT(6));
  3671			fan5pin = !(cr1c & BIT(7));
  3672	
  3673			pwm3pin = !(cr1c & BIT(0));
  3674			pwm4pin = !(cr1c & BIT(1));
  3675			pwm5pin = !(cr1c & BIT(2));
  3676	
  3677			switch (data->kind) {
  3678			case nct6791:
  3679				fan6pin = cr2d & BIT(1);
  3680				pwm6pin = cr2d & BIT(0);
  3681				break;
  3682			case nct6792:
  3683				fan6pin = !dsw_en && (cr2d & BIT(1));
  3684				pwm6pin = !dsw_en && (cr2d & BIT(0));
  3685				break;
  3686			case nct6793:
  3687				fan5pin |= cr1b & BIT(5);
  3688				fan5pin |= creb & BIT(5);
  3689	
  3690				fan6pin = !dsw_en && (cr2d & BIT(1));
  3691				fan6pin |= creb & BIT(3);
  3692	
  3693				pwm5pin |= cr2d & BIT(7);
  3694				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3695	
  3696				pwm6pin = !dsw_en && (cr2d & BIT(0));
  3697				pwm6pin |= creb & BIT(2);
  3698				break;
  3699			case nct6795:
  3700				fan5pin |= cr1b & BIT(5);
  3701				fan5pin |= creb & BIT(5);
  3702	
  3703				fan6pin = (cr2a & BIT(4)) &&
  3704						(!dsw_en || (cred & BIT(4)));
  3705				fan6pin |= creb & BIT(3);
  3706	
  3707				pwm5pin |= cr2d & BIT(7);
  3708				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3709	
  3710				pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
  3711				pwm6pin |= creb & BIT(2);
  3712				break;
  3713			case nct6796:
  3714				fan5pin |= cr1b & BIT(5);
  3715				fan5pin |= (cre0 & BIT(3)) && !(cr1b & BIT(0));
  3716				fan5pin |= creb & BIT(5);
  3717	
  3718				fan6pin = (cr2a & BIT(4)) &&
  3719						(!dsw_en || (cred & BIT(4)));
  3720				fan6pin |= creb & BIT(3);
  3721	
  3722				fan7pin = !(cr2b & BIT(2));
  3723	
  3724				pwm5pin |= cr2d & BIT(7);
  3725				pwm5pin |= (cre0 & BIT(4)) && !(cr1b & BIT(0));
  3726				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3727	
  3728				pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
  3729				pwm6pin |= creb & BIT(2);
  3730	
  3731				pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
  3732				break;
  3733			case nct6797:
  3734				fan5pin |= !ddr4_en && (cr1b & BIT(5));
  3735				fan5pin |= creb & BIT(5);
  3736	
  3737				fan6pin = cr2a & BIT(4);
  3738				fan6pin |= creb & BIT(3);
  3739	
  3740				fan7pin = cr1a & BIT(1);
  3741	
  3742				pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3743				pwm5pin |= !ddr4_en && (cr2d & BIT(7));
  3744	
  3745				pwm6pin = creb & BIT(2);
  3746				pwm6pin |= cred & BIT(2);
  3747	
  3748				pwm7pin = cr1d & BIT(4);
  3749				break;
  3750			case nct6798:
  3751				fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
  3752				fan6pin |= cr2a & BIT(4);
  3753				fan6pin |= creb & BIT(5);
  3754	
  3755				fan7pin = cr1b & BIT(5);
  3756				fan7pin |= !(cr2b & BIT(2));
  3757				fan7pin |= creb & BIT(3);
  3758	
  3759				pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
  3760				pwm6pin |= !(cred & BIT(2)) && (cr2a & BIT(3));
  3761				pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
  3762	
  3763				pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
  3764				pwm7pin |= cr2d & BIT(7);
  3765				pwm7pin |= creb & BIT(2);
  3766				break;
  3767			default:	/* NCT6779D */
  3768				break;
  3769			}
  3770	
  3771			fan4min = fan4pin;
  3772		}
  3773	
  3774		/* fan 1 and 2 (0x03) are always present */
  3775		data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
  3776			(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
  3777		data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
  3778			(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
  3779		data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
  3780			(pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
  3781	}
  3782	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 35738 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] hwmon: (nct6775) Support access via Asus WMI
  2021-09-12 11:05 [PATCH v3 0/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
  2021-09-12 11:05 ` [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*() Denis Pauk
  2021-09-12 11:05 ` [PATCH v3 2/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
@ 2021-09-12 15:14 ` Andy Shevchenko
  2 siblings, 0 replies; 7+ messages in thread
From: Andy Shevchenko @ 2021-09-12 15:14 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Bernhard Seibold, Pär Ekholm, to.eivind,
	Artem S . Tashkinov, Vittorio Roberto Alfieri, Sahan Fernando,
	Guenter Roeck, Jean Delvare, linux-hwmon, linux-kernel

On Sun, Sep 12, 2021 at 02:05:55PM +0300, Denis Pauk wrote:
> Support accessing the NCT677x via Asus WMI functions.
> 
> On mainboards that support this way of accessing the chip,
> the driver will usually not work without this option since
> in these mainboards, ACPI will mark the I/O port as used.
> 
> @Andy Shevchenko, I have left type of sioreg, in other places
> sioreg has same integer type, should I change all occurrences
> of usage?
> @Guenter Roeck, I have left nct6775_*_set_back() call without
> changes as its always called from platform specific callbacks.
> 
> Could you please review?
> 
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
> Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
> Co-developed-by: Bernhard Seibold <mail@bernhard-seibold.de>
> Signed-off-by: Bernhard Seibold <mail@bernhard-seibold.de>
> Tested-by: Pär Ekholm <pehlm@pekholm.org>
> Tested-by: <to.eivind@gmail.com>
> Tested-by: Artem S. Tashkinov <aros@gmx.com>
> Tested-by: Vittorio Roberto Alfieri <me@rebtoor.com>
> Tested-by: Sahan Fernando <sahan.h.fernando@gmail.com>

This should go to the actual patch that makes it work (preparatory patches may
or may not have all above be listed).

As kbuild bot rightfully noted, the series has to be bisectable.

Compile time bisectability means: each patch should compile incrementally.
And run-time bisectability means: the device should work with each patch
applied incrementally.

I.o.w. you have to compile and boot kernel as many times as patches in your
series + 1 (the clean build of the base).

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-09-12 15:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-12 11:05 [PATCH v3 0/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
2021-09-12 11:05 ` [PATCH v3 1/2] hwmon: (nct6775) Use sio_data in superio_*() Denis Pauk
2021-09-12 14:50   ` kernel test robot
2021-09-12 14:50     ` kernel test robot
2021-09-12 11:05 ` [PATCH v3 2/2] hwmon: (nct6775) Support access via Asus WMI Denis Pauk
2021-09-12 12:47   ` kernel test robot
2021-09-12 15:14 ` [PATCH v3 0/2] " Andy Shevchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.