summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/mlxreg-fan.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c
index 0ba9195c9d71..137a90dd2075 100644
--- a/drivers/hwmon/mlxreg-fan.c
+++ b/drivers/hwmon/mlxreg-fan.c
@@ -63,12 +63,14 @@ struct mlxreg_fan;
* @reg: register offset;
* @mask: fault mask;
* @prsnt: present register offset;
+ * @shift: tacho presence bit shift;
*/
struct mlxreg_fan_tacho {
bool connected;
u32 reg;
u32 mask;
u32 prsnt;
+ u32 shift;
};
/*
@@ -143,8 +145,10 @@ mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
/*
* Map channel to presence bit - drawer can be equipped with
* one or few FANs, while presence is indicated per drawer.
+ * Shift channel value if necessary to align with register value.
*/
- if (BIT(channel / fan->tachos_per_drwr) & regval) {
+ if (BIT(rol32(channel, tacho->shift) / fan->tachos_per_drwr) &
+ regval) {
/* FAN is not connected - return zero for FAN speed. */
*val = 0;
return 0;
@@ -408,7 +412,7 @@ static int mlxreg_fan_connect_verify(struct mlxreg_fan *fan,
return err;
}
- return !!(regval & data->bit);
+ return data->slot ? (data->slot <= regval ? 1 : 0) : !!(regval & data->bit);
}
static int mlxreg_pwm_connect_verify(struct mlxreg_fan *fan,
@@ -545,7 +549,15 @@ static int mlxreg_fan_config(struct mlxreg_fan *fan,
return err;
}
- drwr_avail = hweight32(regval);
+ /*
+ * The number of drawers could be specified in registers by counters for newer
+ * systems, or by bitmasks for older systems. In case the data is provided by
+ * counter, it is indicated through 'version' field.
+ */
+ if (pdata->version)
+ drwr_avail = regval;
+ else
+ drwr_avail = hweight32(regval);
if (!tacho_avail || !drwr_avail || tacho_avail < drwr_avail) {
dev_err(fan->dev, "Configuration is invalid: drawers num %d tachos num %d\n",
drwr_avail, tacho_avail);