Skip to content
/ linux Public

Commit d7efb2e

Browse files
vadimp-nvidiagroeck
authored andcommitted
hwmon: (mlxreg-fan) Extend driver to support multiply cooling devices
Add support for additional cooling devices in order to support the systems, which can be equipped with up-to four PWM controllers. Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent 150f1e0 commit d7efb2e

File tree

1 file changed

+47
-26
lines changed

1 file changed

+47
-26
lines changed

drivers/hwmon/mlxreg-fan.c

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
MLXREG_FAN_MAX_DUTY, \
6464
MLXREG_FAN_MAX_STATE))
6565

66+
struct mlxreg_fan;
67+
6668
/*
6769
* struct mlxreg_fan_tacho - tachometer data (internal use):
6870
*
@@ -81,12 +83,18 @@ struct mlxreg_fan_tacho {
8183
/*
8284
* struct mlxreg_fan_pwm - PWM data (internal use):
8385
*
86+
* @fan: private data;
8487
* @connected: indicates if PWM is connected;
8588
* @reg: register offset;
89+
* @cooling: cooling device levels;
90+
* @cdev: cooling device;
8691
*/
8792
struct mlxreg_fan_pwm {
93+
struct mlxreg_fan *fan;
8894
bool connected;
8995
u32 reg;
96+
u8 cooling_levels[MLXREG_FAN_MAX_STATE + 1];
97+
struct thermal_cooling_device *cdev;
9098
};
9199

92100
/*
@@ -99,8 +107,6 @@ struct mlxreg_fan_pwm {
99107
* @tachos_per_drwr - number of tachometers per drawer;
100108
* @samples: minimum allowed samples per pulse;
101109
* @divider: divider value for tachometer RPM calculation;
102-
* @cooling: cooling device levels;
103-
* @cdev: cooling device;
104110
*/
105111
struct mlxreg_fan {
106112
struct device *dev;
@@ -111,8 +117,6 @@ struct mlxreg_fan {
111117
int tachos_per_drwr;
112118
int samples;
113119
int divider;
114-
u8 cooling_levels[MLXREG_FAN_MAX_STATE + 1];
115-
struct thermal_cooling_device *cdev;
116120
};
117121

118122
static int
@@ -305,11 +309,12 @@ static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev,
305309
unsigned long *state)
306310

307311
{
308-
struct mlxreg_fan *fan = cdev->devdata;
312+
struct mlxreg_fan_pwm *pwm = cdev->devdata;
313+
struct mlxreg_fan *fan = pwm->fan;
309314
u32 regval;
310315
int err;
311316

312-
err = regmap_read(fan->regmap, fan->pwm[0].reg, &regval);
317+
err = regmap_read(fan->regmap, pwm->reg, &regval);
313318
if (err) {
314319
dev_err(fan->dev, "Failed to query PWM duty\n");
315320
return err;
@@ -324,7 +329,8 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
324329
unsigned long state)
325330

326331
{
327-
struct mlxreg_fan *fan = cdev->devdata;
332+
struct mlxreg_fan_pwm *pwm = cdev->devdata;
333+
struct mlxreg_fan *fan = pwm->fan;
328334
unsigned long cur_state;
329335
int i, config = 0;
330336
u32 regval;
@@ -348,11 +354,11 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
348354
config = 1;
349355
state -= MLXREG_FAN_MAX_STATE;
350356
for (i = 0; i < state; i++)
351-
fan->cooling_levels[i] = state;
357+
pwm->cooling_levels[i] = state;
352358
for (i = state; i <= MLXREG_FAN_MAX_STATE; i++)
353-
fan->cooling_levels[i] = i;
359+
pwm->cooling_levels[i] = i;
354360

355-
err = regmap_read(fan->regmap, fan->pwm[0].reg, &regval);
361+
err = regmap_read(fan->regmap, pwm->reg, &regval);
356362
if (err) {
357363
dev_err(fan->dev, "Failed to query PWM duty\n");
358364
return err;
@@ -369,8 +375,8 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
369375
return -EINVAL;
370376

371377
/* Normalize the state to the valid speed range. */
372-
state = fan->cooling_levels[state];
373-
err = regmap_write(fan->regmap, fan->pwm[0].reg,
378+
state = pwm->cooling_levels[state];
379+
err = regmap_write(fan->regmap, pwm->reg,
374380
MLXREG_FAN_PWM_STATE2DUTY(state));
375381
if (err) {
376382
dev_err(fan->dev, "Failed to write PWM duty\n");
@@ -541,11 +547,32 @@ static int mlxreg_fan_config(struct mlxreg_fan *fan,
541547
fan->tachos_per_drwr = tacho_avail / drwr_avail;
542548
}
543549

544-
/* Init cooling levels per PWM state. */
545-
for (i = 0; i < MLXREG_FAN_SPEED_MIN_LEVEL; i++)
546-
fan->cooling_levels[i] = MLXREG_FAN_SPEED_MIN_LEVEL;
547-
for (i = MLXREG_FAN_SPEED_MIN_LEVEL; i <= MLXREG_FAN_MAX_STATE; i++)
548-
fan->cooling_levels[i] = i;
550+
return 0;
551+
}
552+
553+
static int mlxreg_fan_cooling_config(struct device *dev, struct mlxreg_fan *fan)
554+
{
555+
int i, j;
556+
557+
for (i = 0; i <= MLXREG_FAN_MAX_PWM; i++) {
558+
struct mlxreg_fan_pwm *pwm = &fan->pwm[i];
559+
560+
if (!pwm->connected)
561+
continue;
562+
pwm->fan = fan;
563+
pwm->cdev = devm_thermal_of_cooling_device_register(dev, NULL, "mlxreg_fan", pwm,
564+
&mlxreg_fan_cooling_ops);
565+
if (IS_ERR(pwm->cdev)) {
566+
dev_err(dev, "Failed to register cooling device\n");
567+
return PTR_ERR(pwm->cdev);
568+
}
569+
570+
/* Init cooling levels per PWM state. */
571+
for (j = 0; j < MLXREG_FAN_SPEED_MIN_LEVEL; j++)
572+
pwm->cooling_levels[j] = MLXREG_FAN_SPEED_MIN_LEVEL;
573+
for (j = MLXREG_FAN_SPEED_MIN_LEVEL; j <= MLXREG_FAN_MAX_STATE; j++)
574+
pwm->cooling_levels[j] = j;
575+
}
549576

550577
return 0;
551578
}
@@ -584,16 +611,10 @@ static int mlxreg_fan_probe(struct platform_device *pdev)
584611
return PTR_ERR(hwm);
585612
}
586613

587-
if (IS_REACHABLE(CONFIG_THERMAL)) {
588-
fan->cdev = devm_thermal_of_cooling_device_register(dev,
589-
NULL, "mlxreg_fan", fan, &mlxreg_fan_cooling_ops);
590-
if (IS_ERR(fan->cdev)) {
591-
dev_err(dev, "Failed to register cooling device\n");
592-
return PTR_ERR(fan->cdev);
593-
}
594-
}
614+
if (IS_REACHABLE(CONFIG_THERMAL))
615+
err = mlxreg_fan_cooling_config(dev, fan);
595616

596-
return 0;
617+
return err;
597618
}
598619

599620
static struct platform_driver mlxreg_fan_driver = {

0 commit comments

Comments
 (0)