127 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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 12static 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 NULL17};18 19static 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 60static 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 78static const struct hwmon_ops ice_hwmon_ops = {79 .is_visible = ice_hwmon_is_visible,80 .read = ice_hwmon_read81};82 83static const struct hwmon_chip_info ice_chip_info = {84 .ops = &ice_hwmon_ops,85 .info = ice_hwmon_info86};87 88static 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 supported92 * 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 102void 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 121void ice_hwmon_exit(struct ice_pf *pf)122{123 if (!pf->hwmon_dev)124 return;125 hwmon_device_unregister(pf->hwmon_dev);126}127