1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2017 Netronome Systems, Inc. */
4 #include <linux/kernel.h>
5 #include <linux/bitops.h>
6 #include <linux/hwmon.h>
8 #include "nfpcore/nfp_cpp.h"
9 #include "nfpcore/nfp_nsp.h"
12 #define NFP_TEMP_MAX (95 * 1000)
13 #define NFP_TEMP_CRIT (105 * 1000)
15 #define NFP_POWER_MAX (25 * 1000 * 1000)
17 static int nfp_hwmon_sensor_id(enum hwmon_sensor_types type
, int channel
)
19 if (type
== hwmon_temp
)
20 return NFP_SENSOR_CHIP_TEMPERATURE
;
21 if (type
== hwmon_power
)
22 return NFP_SENSOR_ASSEMBLY_POWER
+ channel
;
27 nfp_hwmon_read(struct device
*dev
, enum hwmon_sensor_types type
, u32 attr
,
28 int channel
, long *val
)
31 enum hwmon_sensor_types type
;
35 { hwmon_temp
, hwmon_temp_max
, NFP_TEMP_MAX
},
36 { hwmon_temp
, hwmon_temp_crit
, NFP_TEMP_CRIT
},
37 { hwmon_power
, hwmon_power_max
, NFP_POWER_MAX
},
39 struct nfp_pf
*pf
= dev_get_drvdata(dev
);
40 enum nfp_nsp_sensor_id id
;
43 for (i
= 0; i
< ARRAY_SIZE(const_vals
); i
++)
44 if (const_vals
[i
].type
== type
&& const_vals
[i
].attr
== attr
) {
45 *val
= const_vals
[i
].val
;
49 err
= nfp_hwmon_sensor_id(type
, channel
);
54 if (!(pf
->nspi
->sensor_mask
& BIT(id
)))
57 if (type
== hwmon_temp
&& attr
== hwmon_temp_input
)
58 return nfp_hwmon_read_sensor(pf
->cpp
, id
, val
);
59 if (type
== hwmon_power
&& attr
== hwmon_power_input
)
60 return nfp_hwmon_read_sensor(pf
->cpp
, id
, val
);
66 nfp_hwmon_is_visible(const void *data
, enum hwmon_sensor_types type
, u32 attr
,
69 if (type
== hwmon_temp
) {
71 case hwmon_temp_input
:
76 } else if (type
== hwmon_power
) {
78 case hwmon_power_input
:
86 static u32 nfp_chip_config
[] = {
91 static const struct hwmon_channel_info nfp_chip
= {
93 .config
= nfp_chip_config
,
96 static u32 nfp_temp_config
[] = {
97 HWMON_T_INPUT
| HWMON_T_MAX
| HWMON_T_CRIT
,
101 static const struct hwmon_channel_info nfp_temp
= {
103 .config
= nfp_temp_config
,
106 static u32 nfp_power_config
[] = {
107 HWMON_P_INPUT
| HWMON_P_MAX
,
113 static const struct hwmon_channel_info nfp_power
= {
115 .config
= nfp_power_config
,
118 static const struct hwmon_channel_info
*nfp_hwmon_info
[] = {
125 static const struct hwmon_ops nfp_hwmon_ops
= {
126 .is_visible
= nfp_hwmon_is_visible
,
127 .read
= nfp_hwmon_read
,
130 static const struct hwmon_chip_info nfp_chip_info
= {
131 .ops
= &nfp_hwmon_ops
,
132 .info
= nfp_hwmon_info
,
135 int nfp_hwmon_register(struct nfp_pf
*pf
)
137 if (!IS_REACHABLE(CONFIG_HWMON
))
141 nfp_warn(pf
->cpp
, "not registering HWMON (no NSP info)\n");
144 if (!pf
->nspi
->sensor_mask
) {
146 "not registering HWMON (NSP doesn't report sensors)\n");
150 pf
->hwmon_dev
= hwmon_device_register_with_info(&pf
->pdev
->dev
, "nfp",
153 return PTR_ERR_OR_ZERO(pf
->hwmon_dev
);
156 void nfp_hwmon_unregister(struct nfp_pf
*pf
)
158 if (!IS_REACHABLE(CONFIG_HWMON
) || !pf
->hwmon_dev
)
161 hwmon_device_unregister(pf
->hwmon_dev
);