Merge branch 'nvme-5.2-rc2' of git://git.infradead.org/nvme into for-linus
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlxsw / core_hwmon.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
3
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>
9 #include <linux/err.h>
10 #include <linux/sfp.h>
11
12 #include "core.h"
13 #include "core_env.h"
14
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)
18
19 struct mlxsw_hwmon_attr {
20         struct device_attribute dev_attr;
21         struct mlxsw_hwmon *hwmon;
22         unsigned int type_index;
23         char name[32];
24 };
25
26 struct mlxsw_hwmon {
27         struct mlxsw_core *core;
28         const struct mlxsw_bus_info *bus_info;
29         struct device *hwmon_dev;
30         struct attribute_group group;
31         const struct attribute_group *groups[2];
32         struct attribute *attrs[MLXSW_HWMON_ATTR_COUNT + 1];
33         struct mlxsw_hwmon_attr hwmon_attrs[MLXSW_HWMON_ATTR_COUNT];
34         unsigned int attrs_count;
35         u8 sensor_count;
36 };
37
38 static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
39                                      struct device_attribute *attr,
40                                      char *buf)
41 {
42         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
43                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
44         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
45         char mtmp_pl[MLXSW_REG_MTMP_LEN];
46         unsigned int temp;
47         int err;
48
49         mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index,
50                             false, false);
51         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
52         if (err) {
53                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
54                 return err;
55         }
56         mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
57         return sprintf(buf, "%u\n", temp);
58 }
59
60 static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
61                                          struct device_attribute *attr,
62                                          char *buf)
63 {
64         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
65                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
66         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
67         char mtmp_pl[MLXSW_REG_MTMP_LEN];
68         unsigned int temp_max;
69         int err;
70
71         mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index,
72                             false, false);
73         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
74         if (err) {
75                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
76                 return err;
77         }
78         mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL);
79         return sprintf(buf, "%u\n", temp_max);
80 }
81
82 static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
83                                           struct device_attribute *attr,
84                                           const char *buf, size_t len)
85 {
86         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
87                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
88         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
89         char mtmp_pl[MLXSW_REG_MTMP_LEN];
90         unsigned long val;
91         int err;
92
93         err = kstrtoul(buf, 10, &val);
94         if (err)
95                 return err;
96         if (val != 1)
97                 return -EINVAL;
98
99         mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index, true, true);
100         err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
101         if (err) {
102                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to reset temp sensor history\n");
103                 return err;
104         }
105         return len;
106 }
107
108 static ssize_t mlxsw_hwmon_fan_rpm_show(struct device *dev,
109                                         struct device_attribute *attr,
110                                         char *buf)
111 {
112         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
113                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
114         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
115         char mfsm_pl[MLXSW_REG_MFSM_LEN];
116         int err;
117
118         mlxsw_reg_mfsm_pack(mfsm_pl, mlwsw_hwmon_attr->type_index);
119         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsm), mfsm_pl);
120         if (err) {
121                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
122                 return err;
123         }
124         return sprintf(buf, "%u\n", mlxsw_reg_mfsm_rpm_get(mfsm_pl));
125 }
126
127 static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
128                                           struct device_attribute *attr,
129                                           char *buf)
130 {
131         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
132                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
133         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
134         char fore_pl[MLXSW_REG_FORE_LEN];
135         bool fault;
136         int err;
137
138         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(fore), fore_pl);
139         if (err) {
140                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
141                 return err;
142         }
143         mlxsw_reg_fore_unpack(fore_pl, mlwsw_hwmon_attr->type_index, &fault);
144
145         return sprintf(buf, "%u\n", fault);
146 }
147
148 static ssize_t mlxsw_hwmon_pwm_show(struct device *dev,
149                                     struct device_attribute *attr,
150                                     char *buf)
151 {
152         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
153                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
154         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
155         char mfsc_pl[MLXSW_REG_MFSC_LEN];
156         int err;
157
158         mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, 0);
159         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
160         if (err) {
161                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query PWM\n");
162                 return err;
163         }
164         return sprintf(buf, "%u\n",
165                        mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl));
166 }
167
168 static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
169                                      struct device_attribute *attr,
170                                      const char *buf, size_t len)
171 {
172         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
173                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
174         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
175         char mfsc_pl[MLXSW_REG_MFSC_LEN];
176         unsigned long val;
177         int err;
178
179         err = kstrtoul(buf, 10, &val);
180         if (err)
181                 return err;
182         if (val > 255)
183                 return -EINVAL;
184
185         mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, val);
186         err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
187         if (err) {
188                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to write PWM\n");
189                 return err;
190         }
191         return len;
192 }
193
194 static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
195                                             struct device_attribute *attr,
196                                             char *buf)
197 {
198         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
199                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
200         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
201         char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
202         u16 temp;
203         u8 module;
204         int err;
205
206         module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
207         mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
208                             1);
209         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
210         if (err) {
211                 dev_err(dev, "Failed to query module temperature sensor\n");
212                 return err;
213         }
214
215         mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
216         /* Update status and temperature cache. */
217         switch (temp) {
218         case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
219         case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
220         case MLXSW_REG_MTBR_INDEX_NA:
221                 temp = 0;
222                 break;
223         case MLXSW_REG_MTBR_BAD_SENS_INFO:
224                 /* Untrusted cable is connected. Reading temperature from its
225                  * sensor is faulty.
226                  */
227                 temp = 0;
228                 break;
229         default:
230                 temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
231                 break;
232         }
233
234         return sprintf(buf, "%u\n", temp);
235 }
236
237 static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
238                                                   struct device_attribute *attr,
239                                                   char *buf)
240 {
241         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
242                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
243         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
244         char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
245         u8 module, fault;
246         u16 temp;
247         int err;
248
249         module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
250         mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
251                             1);
252         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
253         if (err) {
254                 dev_err(dev, "Failed to query module temperature sensor\n");
255                 return err;
256         }
257
258         mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
259
260         /* Update status and temperature cache. */
261         switch (temp) {
262         case MLXSW_REG_MTBR_BAD_SENS_INFO:
263                 /* Untrusted cable is connected. Reading temperature from its
264                  * sensor is faulty.
265                  */
266                 fault = 1;
267                 break;
268         case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
269         case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
270         case MLXSW_REG_MTBR_INDEX_NA:
271         default:
272                 fault = 0;
273                 break;
274         }
275
276         return sprintf(buf, "%u\n", fault);
277 }
278
279 static ssize_t
280 mlxsw_hwmon_module_temp_critical_show(struct device *dev,
281                                       struct device_attribute *attr, char *buf)
282 {
283         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
284                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
285         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
286         int temp;
287         u8 module;
288         int err;
289
290         module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
291         err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
292                                                    SFP_TEMP_HIGH_WARN, &temp);
293         if (err) {
294                 dev_err(dev, "Failed to query module temperature thresholds\n");
295                 return err;
296         }
297
298         return sprintf(buf, "%u\n", temp);
299 }
300
301 static ssize_t
302 mlxsw_hwmon_module_temp_emergency_show(struct device *dev,
303                                        struct device_attribute *attr,
304                                        char *buf)
305 {
306         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
307                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
308         struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
309         u8 module;
310         int temp;
311         int err;
312
313         module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
314         err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
315                                                    SFP_TEMP_HIGH_ALARM, &temp);
316         if (err) {
317                 dev_err(dev, "Failed to query module temperature thresholds\n");
318                 return err;
319         }
320
321         return sprintf(buf, "%u\n", temp);
322 }
323
324 static ssize_t
325 mlxsw_hwmon_module_temp_label_show(struct device *dev,
326                                    struct device_attribute *attr,
327                                    char *buf)
328 {
329         struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
330                         container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
331
332         return sprintf(buf, "front panel %03u\n",
333                        mlwsw_hwmon_attr->type_index);
334 }
335
336 enum mlxsw_hwmon_attr_type {
337         MLXSW_HWMON_ATTR_TYPE_TEMP,
338         MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
339         MLXSW_HWMON_ATTR_TYPE_TEMP_RST,
340         MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
341         MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
342         MLXSW_HWMON_ATTR_TYPE_PWM,
343         MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE,
344         MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
345         MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT,
346         MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
347         MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
348 };
349
350 static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
351                                  enum mlxsw_hwmon_attr_type attr_type,
352                                  unsigned int type_index, unsigned int num) {
353         struct mlxsw_hwmon_attr *mlxsw_hwmon_attr;
354         unsigned int attr_index;
355
356         attr_index = mlxsw_hwmon->attrs_count;
357         mlxsw_hwmon_attr = &mlxsw_hwmon->hwmon_attrs[attr_index];
358
359         switch (attr_type) {
360         case MLXSW_HWMON_ATTR_TYPE_TEMP:
361                 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
362                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
363                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
364                          "temp%u_input", num + 1);
365                 break;
366         case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
367                 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
368                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
369                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
370                          "temp%u_highest", num + 1);
371                 break;
372         case MLXSW_HWMON_ATTR_TYPE_TEMP_RST:
373                 mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_temp_rst_store;
374                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0200;
375                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
376                          "temp%u_reset_history", num + 1);
377                 break;
378         case MLXSW_HWMON_ATTR_TYPE_FAN_RPM:
379                 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_fan_rpm_show;
380                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
381                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
382                          "fan%u_input", num + 1);
383                 break;
384         case MLXSW_HWMON_ATTR_TYPE_FAN_FAULT:
385                 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_fan_fault_show;
386                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
387                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
388                          "fan%u_fault", num + 1);
389                 break;
390         case MLXSW_HWMON_ATTR_TYPE_PWM:
391                 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_pwm_show;
392                 mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_pwm_store;
393                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0644;
394                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
395                          "pwm%u", num + 1);
396                 break;
397         case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE:
398                 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_module_temp_show;
399                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
400                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
401                          "temp%u_input", num + 1);
402                 break;
403         case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT:
404                 mlxsw_hwmon_attr->dev_attr.show =
405                                         mlxsw_hwmon_module_temp_fault_show;
406                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
407                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
408                          "temp%u_fault", num + 1);
409                 break;
410         case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT:
411                 mlxsw_hwmon_attr->dev_attr.show =
412                         mlxsw_hwmon_module_temp_critical_show;
413                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
414                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
415                          "temp%u_crit", num + 1);
416                 break;
417         case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG:
418                 mlxsw_hwmon_attr->dev_attr.show =
419                         mlxsw_hwmon_module_temp_emergency_show;
420                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
421                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
422                          "temp%u_emergency", num + 1);
423                 break;
424         case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL:
425                 mlxsw_hwmon_attr->dev_attr.show =
426                         mlxsw_hwmon_module_temp_label_show;
427                 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
428                 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
429                          "temp%u_label", num + 1);
430                 break;
431         default:
432                 WARN_ON(1);
433         }
434
435         mlxsw_hwmon_attr->type_index = type_index;
436         mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
437         mlxsw_hwmon_attr->dev_attr.attr.name = mlxsw_hwmon_attr->name;
438         sysfs_attr_init(&mlxsw_hwmon_attr->dev_attr.attr);
439
440         mlxsw_hwmon->attrs[attr_index] = &mlxsw_hwmon_attr->dev_attr.attr;
441         mlxsw_hwmon->attrs_count++;
442 }
443
444 static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
445 {
446         char mtcap_pl[MLXSW_REG_MTCAP_LEN] = {0};
447         char mtmp_pl[MLXSW_REG_MTMP_LEN];
448         int i;
449         int err;
450
451         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtcap), mtcap_pl);
452         if (err) {
453                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get number of temp sensors\n");
454                 return err;
455         }
456         mlxsw_hwmon->sensor_count = mlxsw_reg_mtcap_sensor_count_get(mtcap_pl);
457         for (i = 0; i < mlxsw_hwmon->sensor_count; i++) {
458                 mlxsw_reg_mtmp_pack(mtmp_pl, i, true, true);
459                 err = mlxsw_reg_write(mlxsw_hwmon->core,
460                                       MLXSW_REG(mtmp), mtmp_pl);
461                 if (err) {
462                         dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
463                                 i);
464                         return err;
465                 }
466                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
467                                      MLXSW_HWMON_ATTR_TYPE_TEMP, i, i);
468                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
469                                      MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, i, i);
470                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
471                                      MLXSW_HWMON_ATTR_TYPE_TEMP_RST, i, i);
472         }
473         return 0;
474 }
475
476 static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
477 {
478         char mfcr_pl[MLXSW_REG_MFCR_LEN] = {0};
479         enum mlxsw_reg_mfcr_pwm_frequency freq;
480         unsigned int type_index;
481         unsigned int num;
482         u16 tacho_active;
483         u8 pwm_active;
484         int err;
485
486         err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfcr), mfcr_pl);
487         if (err) {
488                 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get to probe PWMs and Tachometers\n");
489                 return err;
490         }
491         mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
492         num = 0;
493         for (type_index = 0; type_index < MLXSW_MFCR_TACHOS_MAX; type_index++) {
494                 if (tacho_active & BIT(type_index)) {
495                         mlxsw_hwmon_attr_add(mlxsw_hwmon,
496                                              MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
497                                              type_index, num);
498                         mlxsw_hwmon_attr_add(mlxsw_hwmon,
499                                              MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
500                                              type_index, num++);
501                 }
502         }
503         num = 0;
504         for (type_index = 0; type_index < MLXSW_MFCR_PWMS_MAX; type_index++) {
505                 if (pwm_active & BIT(type_index))
506                         mlxsw_hwmon_attr_add(mlxsw_hwmon,
507                                              MLXSW_HWMON_ATTR_TYPE_PWM,
508                                              type_index, num++);
509         }
510         return 0;
511 }
512
513 static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
514 {
515         unsigned int module_count = mlxsw_core_max_ports(mlxsw_hwmon->core);
516         char pmlp_pl[MLXSW_REG_PMLP_LEN] = {0};
517         int i, index;
518         u8 width;
519         int err;
520
521         /* Add extra attributes for module temperature. Sensor index is
522          * assigned to sensor_count value, while all indexed before
523          * sensor_count are already utilized by the sensors connected through
524          * mtmp register by mlxsw_hwmon_temp_init().
525          */
526         index = mlxsw_hwmon->sensor_count;
527         for (i = 1; i < module_count; i++) {
528                 mlxsw_reg_pmlp_pack(pmlp_pl, i);
529                 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(pmlp),
530                                       pmlp_pl);
531                 if (err) {
532                         dev_err(mlxsw_hwmon->bus_info->dev, "Failed to read module index %d\n",
533                                 i);
534                         return err;
535                 }
536                 width = mlxsw_reg_pmlp_width_get(pmlp_pl);
537                 if (!width)
538                         continue;
539                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
540                                      MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE, index,
541                                      index);
542                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
543                                      MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
544                                      index, index);
545                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
546                                      MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT,
547                                      index, index);
548                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
549                                      MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
550                                      index, index);
551                 mlxsw_hwmon_attr_add(mlxsw_hwmon,
552                                      MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
553                                      index, index);
554                 index++;
555         }
556
557         return 0;
558 }
559
560 int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
561                      const struct mlxsw_bus_info *mlxsw_bus_info,
562                      struct mlxsw_hwmon **p_hwmon)
563 {
564         struct mlxsw_hwmon *mlxsw_hwmon;
565         struct device *hwmon_dev;
566         int err;
567
568         mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
569         if (!mlxsw_hwmon)
570                 return -ENOMEM;
571         mlxsw_hwmon->core = mlxsw_core;
572         mlxsw_hwmon->bus_info = mlxsw_bus_info;
573
574         err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
575         if (err)
576                 goto err_temp_init;
577
578         err = mlxsw_hwmon_fans_init(mlxsw_hwmon);
579         if (err)
580                 goto err_fans_init;
581
582         err = mlxsw_hwmon_module_init(mlxsw_hwmon);
583         if (err)
584                 goto err_temp_module_init;
585
586         mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
587         mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
588
589         hwmon_dev = hwmon_device_register_with_groups(mlxsw_bus_info->dev,
590                                                       "mlxsw", mlxsw_hwmon,
591                                                       mlxsw_hwmon->groups);
592         if (IS_ERR(hwmon_dev)) {
593                 err = PTR_ERR(hwmon_dev);
594                 goto err_hwmon_register;
595         }
596
597         mlxsw_hwmon->hwmon_dev = hwmon_dev;
598         *p_hwmon = mlxsw_hwmon;
599         return 0;
600
601 err_hwmon_register:
602 err_temp_module_init:
603 err_fans_init:
604 err_temp_init:
605         kfree(mlxsw_hwmon);
606         return err;
607 }
608
609 void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
610 {
611         hwmon_device_unregister(mlxsw_hwmon->hwmon_dev);
612         kfree(mlxsw_hwmon);
613 }