// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2017 Chelsio Communications. All rights reserved. * * Written by: Ganesh Goudar (ganeshgr@chelsio.com) */ #include "cxgb4.h" #define CXGB4_NUM_TRIPS 1 static int cxgb4_thermal_get_temp(struct thermal_zone_device *tzdev, int *temp) { struct adapter *adap = tzdev->devdata; u32 param, val; int ret; param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) | FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_TMP)); ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); if (ret < 0 || val == 0) return -1; *temp = val * 1000; return 0; } static int cxgb4_thermal_get_trip_type(struct thermal_zone_device *tzdev, int trip, enum thermal_trip_type *type) { struct adapter *adap = tzdev->devdata; if (!adap->ch_thermal.trip_temp) return -EINVAL; *type = adap->ch_thermal.trip_type; return 0; } static int cxgb4_thermal_get_trip_temp(struct thermal_zone_device *tzdev, int trip, int *temp) { struct adapter *adap = tzdev->devdata; if (!adap->ch_thermal.trip_temp) return -EINVAL; *temp = adap->ch_thermal.trip_temp; return 0; } static struct thermal_zone_device_ops cxgb4_thermal_ops = { .get_temp = cxgb4_thermal_get_temp, .get_trip_type = cxgb4_thermal_get_trip_type, .get_trip_temp = cxgb4_thermal_get_trip_temp, }; int cxgb4_thermal_init(struct adapter *adap) { struct ch_thermal *ch_thermal = &adap->ch_thermal; int num_trip = CXGB4_NUM_TRIPS; u32 param, val; int ret; /* on older firmwares we may not get the trip temperature, * set the num of trips to 0. */ param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) | FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_MAXTMPTHRESH)); ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); if (ret < 0) { num_trip = 0; /* could not get trip temperature */ } else { ch_thermal->trip_temp = val * 1000; ch_thermal->trip_type = THERMAL_TRIP_CRITICAL; } ch_thermal->tzdev = thermal_zone_device_register("cxgb4", num_trip, 0, adap, &cxgb4_thermal_ops, NULL, 0, 0); if (IS_ERR(ch_thermal->tzdev)) { ret = PTR_ERR(ch_thermal->tzdev); dev_err(adap->pdev_dev, "Failed to register thermal zone\n"); ch_thermal->tzdev = NULL; return ret; } return 0; } int cxgb4_thermal_remove(struct adapter *adap) { if (adap->ch_thermal.tzdev) thermal_zone_device_unregister(adap->ch_thermal.tzdev); return 0; }