/*
 *  Copyright (C) 2017 Chelsio Communications.  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms and conditions of the GNU General Public License,
 *  version 2, as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 *  more details.
 *
 *  The full GNU General Public License is included in this distribution in
 *  the file called "COPYING".
 *
 *  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,
			      &param, &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,
			      &param, &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;
}
