]> Git Repo - J-linux.git/blob - drivers/net/ethernet/intel/ice/ice_hwmon.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / ethernet / intel / ice / ice_hwmon.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2023, Intel Corporation. */
3
4 #include "ice.h"
5 #include "ice_hwmon.h"
6 #include "ice_adminq_cmd.h"
7
8 #include <linux/hwmon.h>
9
10 #define TEMP_FROM_REG(reg) ((reg) * 1000)
11
12 static const struct hwmon_channel_info *ice_hwmon_info[] = {
13         HWMON_CHANNEL_INFO(temp,
14                            HWMON_T_INPUT | HWMON_T_MAX |
15                            HWMON_T_CRIT | HWMON_T_EMERGENCY),
16         NULL
17 };
18
19 static int ice_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
20                           u32 attr, int channel, long *val)
21 {
22         struct ice_aqc_get_sensor_reading_resp resp;
23         struct ice_pf *pf = dev_get_drvdata(dev);
24         int ret;
25
26         if (type != hwmon_temp)
27                 return -EOPNOTSUPP;
28
29         ret = ice_aq_get_sensor_reading(&pf->hw, &resp);
30         if (ret) {
31                 dev_warn_ratelimited(dev,
32                                      "%s HW read failure (%d)\n",
33                                      __func__,
34                                      ret);
35                 return ret;
36         }
37
38         switch (attr) {
39         case hwmon_temp_input:
40                 *val = TEMP_FROM_REG(resp.data.s0f0.temp);
41                 break;
42         case hwmon_temp_max:
43                 *val = TEMP_FROM_REG(resp.data.s0f0.temp_warning_threshold);
44                 break;
45         case hwmon_temp_crit:
46                 *val = TEMP_FROM_REG(resp.data.s0f0.temp_critical_threshold);
47                 break;
48         case hwmon_temp_emergency:
49                 *val = TEMP_FROM_REG(resp.data.s0f0.temp_fatal_threshold);
50                 break;
51         default:
52                 dev_dbg(dev, "%s unsupported attribute (%d)\n",
53                         __func__, attr);
54                 return -EOPNOTSUPP;
55         }
56
57         return 0;
58 }
59
60 static umode_t ice_hwmon_is_visible(const void *data,
61                                     enum hwmon_sensor_types type, u32 attr,
62                                     int channel)
63 {
64         if (type != hwmon_temp)
65                 return 0;
66
67         switch (attr) {
68         case hwmon_temp_input:
69         case hwmon_temp_crit:
70         case hwmon_temp_max:
71         case hwmon_temp_emergency:
72                 return 0444;
73         }
74
75         return 0;
76 }
77
78 static const struct hwmon_ops ice_hwmon_ops = {
79         .is_visible = ice_hwmon_is_visible,
80         .read = ice_hwmon_read
81 };
82
83 static const struct hwmon_chip_info ice_chip_info = {
84         .ops = &ice_hwmon_ops,
85         .info = ice_hwmon_info
86 };
87
88 static bool ice_is_internal_reading_supported(struct ice_pf *pf)
89 {
90         /* Only the first PF will report temperature for a chip.
91          * Note that internal temp reading is not supported
92          * for older FW (< v4.30).
93          */
94         if (pf->hw.pf_id)
95                 return false;
96
97         unsigned long sensors = pf->hw.dev_caps.supported_sensors;
98
99         return test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors);
100 };
101
102 void ice_hwmon_init(struct ice_pf *pf)
103 {
104         struct device *dev = ice_pf_to_dev(pf);
105         struct device *hdev;
106
107         if (!ice_is_internal_reading_supported(pf))
108                 return;
109
110         hdev = hwmon_device_register_with_info(dev, "ice", pf, &ice_chip_info,
111                                                NULL);
112         if (IS_ERR(hdev)) {
113                 dev_warn(dev,
114                          "hwmon_device_register_with_info returns error (%ld)",
115                          PTR_ERR(hdev));
116                 return;
117         }
118         pf->hwmon_dev = hdev;
119 }
120
121 void ice_hwmon_exit(struct ice_pf *pf)
122 {
123         if (!pf->hwmon_dev)
124                 return;
125         hwmon_device_unregister(pf->hwmon_dev);
126 }
This page took 0.032447 seconds and 4 git commands to generate.