1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
4 #include <linux/kernel.h>
5 #include <linux/types.h>
6 #include <linux/device.h>
7 #include <linux/sysfs.h>
8 #include <linux/hwmon.h>
10 #include <linux/sfp.h>
15 #define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127
16 #define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4 + \
17 MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
19 struct mlxsw_hwmon_attr {
20 struct device_attribute dev_attr;
21 struct mlxsw_hwmon *hwmon;
22 unsigned int type_index;
26 static int mlxsw_hwmon_get_attr_index(int index, int count)
29 return index % count + MLXSW_REG_MTMP_GBOX_INDEX_MIN;
35 struct mlxsw_core *core;
36 const struct mlxsw_bus_info *bus_info;
37 struct device *hwmon_dev;
38 struct attribute_group group;
39 const struct attribute_group *groups[2];
40 struct attribute *attrs[MLXSW_HWMON_ATTR_COUNT + 1];
41 struct mlxsw_hwmon_attr hwmon_attrs[MLXSW_HWMON_ATTR_COUNT];
42 unsigned int attrs_count;
47 static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
48 struct device_attribute *attr,
51 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
52 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
53 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
54 char mtmp_pl[MLXSW_REG_MTMP_LEN];
58 index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
59 mlxsw_hwmon->module_sensor_max);
60 mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
61 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
63 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
66 mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
67 return sprintf(buf, "%d\n", temp);
70 static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
71 struct device_attribute *attr,
74 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
75 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
76 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
77 char mtmp_pl[MLXSW_REG_MTMP_LEN];
81 index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
82 mlxsw_hwmon->module_sensor_max);
83 mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
84 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
86 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
89 mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL);
90 return sprintf(buf, "%d\n", temp_max);
93 static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
94 struct device_attribute *attr,
95 const char *buf, size_t len)
97 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
98 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
99 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
100 char mtmp_pl[MLXSW_REG_MTMP_LEN];
105 err = kstrtoul(buf, 10, &val);
111 index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
112 mlxsw_hwmon->module_sensor_max);
113 mlxsw_reg_mtmp_pack(mtmp_pl, index, true, true);
114 err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
116 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to reset temp sensor history\n");
122 static ssize_t mlxsw_hwmon_fan_rpm_show(struct device *dev,
123 struct device_attribute *attr,
126 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
127 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
128 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
129 char mfsm_pl[MLXSW_REG_MFSM_LEN];
132 mlxsw_reg_mfsm_pack(mfsm_pl, mlwsw_hwmon_attr->type_index);
133 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsm), mfsm_pl);
135 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
138 return sprintf(buf, "%u\n", mlxsw_reg_mfsm_rpm_get(mfsm_pl));
141 static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
142 struct device_attribute *attr,
145 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
146 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
147 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
148 char fore_pl[MLXSW_REG_FORE_LEN];
152 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(fore), fore_pl);
154 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
157 mlxsw_reg_fore_unpack(fore_pl, mlwsw_hwmon_attr->type_index, &fault);
159 return sprintf(buf, "%u\n", fault);
162 static ssize_t mlxsw_hwmon_pwm_show(struct device *dev,
163 struct device_attribute *attr,
166 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
167 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
168 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
169 char mfsc_pl[MLXSW_REG_MFSC_LEN];
172 mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, 0);
173 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
175 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query PWM\n");
178 return sprintf(buf, "%u\n",
179 mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl));
182 static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
183 struct device_attribute *attr,
184 const char *buf, size_t len)
186 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
187 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
188 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
189 char mfsc_pl[MLXSW_REG_MFSC_LEN];
193 err = kstrtoul(buf, 10, &val);
199 mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, val);
200 err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
202 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to write PWM\n");
208 static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
209 struct device_attribute *attr,
212 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
213 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
214 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
215 char mtmp_pl[MLXSW_REG_MTMP_LEN];
220 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
221 mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
223 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
226 mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
228 return sprintf(buf, "%d\n", temp);
231 static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
232 struct device_attribute *attr,
235 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
236 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
237 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
238 char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
243 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
244 mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
246 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
248 dev_err(dev, "Failed to query module temperature sensor\n");
252 mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
254 /* Update status and temperature cache. */
256 case MLXSW_REG_MTBR_BAD_SENS_INFO:
257 /* Untrusted cable is connected. Reading temperature from its
262 case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
263 case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
264 case MLXSW_REG_MTBR_INDEX_NA:
270 return sprintf(buf, "%u\n", fault);
274 mlxsw_hwmon_module_temp_critical_show(struct device *dev,
275 struct device_attribute *attr, char *buf)
277 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
278 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
279 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
284 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
285 err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
286 SFP_TEMP_HIGH_WARN, &temp);
288 dev_err(dev, "Failed to query module temperature thresholds\n");
292 return sprintf(buf, "%u\n", temp);
296 mlxsw_hwmon_module_temp_emergency_show(struct device *dev,
297 struct device_attribute *attr,
300 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
301 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
302 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
307 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
308 err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
309 SFP_TEMP_HIGH_ALARM, &temp);
311 dev_err(dev, "Failed to query module temperature thresholds\n");
315 return sprintf(buf, "%u\n", temp);
319 mlxsw_hwmon_module_temp_label_show(struct device *dev,
320 struct device_attribute *attr,
323 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
324 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
326 return sprintf(buf, "front panel %03u\n",
327 mlwsw_hwmon_attr->type_index);
331 mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
332 struct device_attribute *attr,
335 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
336 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
337 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
338 int index = mlwsw_hwmon_attr->type_index -
339 mlxsw_hwmon->module_sensor_max + 1;
341 return sprintf(buf, "gearbox %03u\n", index);
344 enum mlxsw_hwmon_attr_type {
345 MLXSW_HWMON_ATTR_TYPE_TEMP,
346 MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
347 MLXSW_HWMON_ATTR_TYPE_TEMP_RST,
348 MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
349 MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
350 MLXSW_HWMON_ATTR_TYPE_PWM,
351 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE,
352 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
353 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT,
354 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
355 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
356 MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
359 static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
360 enum mlxsw_hwmon_attr_type attr_type,
361 unsigned int type_index, unsigned int num) {
362 struct mlxsw_hwmon_attr *mlxsw_hwmon_attr;
363 unsigned int attr_index;
365 attr_index = mlxsw_hwmon->attrs_count;
366 mlxsw_hwmon_attr = &mlxsw_hwmon->hwmon_attrs[attr_index];
369 case MLXSW_HWMON_ATTR_TYPE_TEMP:
370 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
371 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
372 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
373 "temp%u_input", num + 1);
375 case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
376 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
377 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
378 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
379 "temp%u_highest", num + 1);
381 case MLXSW_HWMON_ATTR_TYPE_TEMP_RST:
382 mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_temp_rst_store;
383 mlxsw_hwmon_attr->dev_attr.attr.mode = 0200;
384 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
385 "temp%u_reset_history", num + 1);
387 case MLXSW_HWMON_ATTR_TYPE_FAN_RPM:
388 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_fan_rpm_show;
389 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
390 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
391 "fan%u_input", num + 1);
393 case MLXSW_HWMON_ATTR_TYPE_FAN_FAULT:
394 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_fan_fault_show;
395 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
396 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
397 "fan%u_fault", num + 1);
399 case MLXSW_HWMON_ATTR_TYPE_PWM:
400 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_pwm_show;
401 mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_pwm_store;
402 mlxsw_hwmon_attr->dev_attr.attr.mode = 0644;
403 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
406 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE:
407 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_module_temp_show;
408 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
409 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
410 "temp%u_input", num + 1);
412 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT:
413 mlxsw_hwmon_attr->dev_attr.show =
414 mlxsw_hwmon_module_temp_fault_show;
415 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
416 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
417 "temp%u_fault", num + 1);
419 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT:
420 mlxsw_hwmon_attr->dev_attr.show =
421 mlxsw_hwmon_module_temp_critical_show;
422 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
423 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
424 "temp%u_crit", num + 1);
426 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG:
427 mlxsw_hwmon_attr->dev_attr.show =
428 mlxsw_hwmon_module_temp_emergency_show;
429 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
430 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
431 "temp%u_emergency", num + 1);
433 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL:
434 mlxsw_hwmon_attr->dev_attr.show =
435 mlxsw_hwmon_module_temp_label_show;
436 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
437 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
438 "temp%u_label", num + 1);
440 case MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL:
441 mlxsw_hwmon_attr->dev_attr.show =
442 mlxsw_hwmon_gbox_temp_label_show;
443 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
444 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
445 "temp%u_label", num + 1);
451 mlxsw_hwmon_attr->type_index = type_index;
452 mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
453 mlxsw_hwmon_attr->dev_attr.attr.name = mlxsw_hwmon_attr->name;
454 sysfs_attr_init(&mlxsw_hwmon_attr->dev_attr.attr);
456 mlxsw_hwmon->attrs[attr_index] = &mlxsw_hwmon_attr->dev_attr.attr;
457 mlxsw_hwmon->attrs_count++;
460 static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
462 char mtcap_pl[MLXSW_REG_MTCAP_LEN] = {0};
463 char mtmp_pl[MLXSW_REG_MTMP_LEN];
467 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtcap), mtcap_pl);
469 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get number of temp sensors\n");
472 mlxsw_hwmon->sensor_count = mlxsw_reg_mtcap_sensor_count_get(mtcap_pl);
473 for (i = 0; i < mlxsw_hwmon->sensor_count; i++) {
474 mlxsw_reg_mtmp_pack(mtmp_pl, i, true, true);
475 err = mlxsw_reg_write(mlxsw_hwmon->core,
476 MLXSW_REG(mtmp), mtmp_pl);
478 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
482 mlxsw_hwmon_attr_add(mlxsw_hwmon,
483 MLXSW_HWMON_ATTR_TYPE_TEMP, i, i);
484 mlxsw_hwmon_attr_add(mlxsw_hwmon,
485 MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, i, i);
486 mlxsw_hwmon_attr_add(mlxsw_hwmon,
487 MLXSW_HWMON_ATTR_TYPE_TEMP_RST, i, i);
492 static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
494 char mfcr_pl[MLXSW_REG_MFCR_LEN] = {0};
495 enum mlxsw_reg_mfcr_pwm_frequency freq;
496 unsigned int type_index;
502 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfcr), mfcr_pl);
504 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get to probe PWMs and Tachometers\n");
507 mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
509 for (type_index = 0; type_index < MLXSW_MFCR_TACHOS_MAX; type_index++) {
510 if (tacho_active & BIT(type_index)) {
511 mlxsw_hwmon_attr_add(mlxsw_hwmon,
512 MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
514 mlxsw_hwmon_attr_add(mlxsw_hwmon,
515 MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
520 for (type_index = 0; type_index < MLXSW_MFCR_PWMS_MAX; type_index++) {
521 if (pwm_active & BIT(type_index))
522 mlxsw_hwmon_attr_add(mlxsw_hwmon,
523 MLXSW_HWMON_ATTR_TYPE_PWM,
529 static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
531 char mgpir_pl[MLXSW_REG_MGPIR_LEN];
532 u8 module_sensor_max;
535 if (!mlxsw_core_res_query_enabled(mlxsw_hwmon->core))
538 mlxsw_reg_mgpir_pack(mgpir_pl);
539 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
543 mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
546 /* Add extra attributes for module temperature. Sensor index is
547 * assigned to sensor_count value, while all indexed before
548 * sensor_count are already utilized by the sensors connected through
549 * mtmp register by mlxsw_hwmon_temp_init().
551 mlxsw_hwmon->module_sensor_max = mlxsw_hwmon->sensor_count +
553 for (i = mlxsw_hwmon->sensor_count;
554 i < mlxsw_hwmon->module_sensor_max; i++) {
555 mlxsw_hwmon_attr_add(mlxsw_hwmon,
556 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE, i, i);
557 mlxsw_hwmon_attr_add(mlxsw_hwmon,
558 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
560 mlxsw_hwmon_attr_add(mlxsw_hwmon,
561 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT, i,
563 mlxsw_hwmon_attr_add(mlxsw_hwmon,
564 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
566 mlxsw_hwmon_attr_add(mlxsw_hwmon,
567 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
574 static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
576 int index, max_index, sensor_index;
577 char mgpir_pl[MLXSW_REG_MGPIR_LEN];
578 char mtmp_pl[MLXSW_REG_MTMP_LEN];
582 mlxsw_reg_mgpir_pack(mgpir_pl);
583 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
587 mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, NULL, NULL, NULL);
591 index = mlxsw_hwmon->module_sensor_max;
592 max_index = mlxsw_hwmon->module_sensor_max + gbox_num;
593 while (index < max_index) {
594 sensor_index = index % mlxsw_hwmon->module_sensor_max +
595 MLXSW_REG_MTMP_GBOX_INDEX_MIN;
596 mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, true, true);
597 err = mlxsw_reg_write(mlxsw_hwmon->core,
598 MLXSW_REG(mtmp), mtmp_pl);
600 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
604 mlxsw_hwmon_attr_add(mlxsw_hwmon, MLXSW_HWMON_ATTR_TYPE_TEMP,
606 mlxsw_hwmon_attr_add(mlxsw_hwmon,
607 MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, index,
609 mlxsw_hwmon_attr_add(mlxsw_hwmon,
610 MLXSW_HWMON_ATTR_TYPE_TEMP_RST, index,
612 mlxsw_hwmon_attr_add(mlxsw_hwmon,
613 MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
621 int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
622 const struct mlxsw_bus_info *mlxsw_bus_info,
623 struct mlxsw_hwmon **p_hwmon)
625 struct mlxsw_hwmon *mlxsw_hwmon;
626 struct device *hwmon_dev;
629 mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
632 mlxsw_hwmon->core = mlxsw_core;
633 mlxsw_hwmon->bus_info = mlxsw_bus_info;
635 err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
639 err = mlxsw_hwmon_fans_init(mlxsw_hwmon);
643 err = mlxsw_hwmon_module_init(mlxsw_hwmon);
645 goto err_temp_module_init;
647 err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon);
649 goto err_temp_gearbox_init;
651 mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
652 mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
654 hwmon_dev = hwmon_device_register_with_groups(mlxsw_bus_info->dev,
655 "mlxsw", mlxsw_hwmon,
656 mlxsw_hwmon->groups);
657 if (IS_ERR(hwmon_dev)) {
658 err = PTR_ERR(hwmon_dev);
659 goto err_hwmon_register;
662 mlxsw_hwmon->hwmon_dev = hwmon_dev;
663 *p_hwmon = mlxsw_hwmon;
667 err_temp_gearbox_init:
668 err_temp_module_init:
675 void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
677 hwmon_device_unregister(mlxsw_hwmon->hwmon_dev);