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
);