Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1871915 authored by Ganesh Goudar's avatar Ganesh Goudar Committed by David S. Miller
Browse files

cxgb4: Add thermal zone support



Add thermal zone support to monitor ASIC's temperature.

Signed-off-by: default avatarGanesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 27055454
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -12,3 +12,4 @@ cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o
cxgb4-$(CONFIG_CHELSIO_T4_DCB) +=  cxgb4_dcb.o
cxgb4-$(CONFIG_CHELSIO_T4_FCOE) +=  cxgb4_fcoe.o
cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o
cxgb4-$(CONFIG_THERMAL) += cxgb4_thermal.o
+18 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#include <linux/ptp_clock_kernel.h>
#include <linux/ptp_classify.h>
#include <linux/crash_dump.h>
#include <linux/thermal.h>
#include <asm/io.h>
#include "t4_chip_type.h"
#include "cxgb4_uld.h"
@@ -890,6 +891,14 @@ struct mps_encap_entry {
	atomic_t refcnt;
};

#ifdef CONFIG_THERMAL
struct ch_thermal {
	struct thermal_zone_device *tzdev;
	int trip_temp;
	int trip_type;
};
#endif

struct adapter {
	void __iomem *regs;
	void __iomem *bar2;
@@ -1008,6 +1017,9 @@ struct adapter {

	/* Dump buffer for collecting logs in kdump kernel */
	struct vmcoredd_data vmcoredd;
#ifdef CONFIG_THERMAL
	struct ch_thermal ch_thermal;
#endif
};

/* Support for "sched-class" command to allow a TX Scheduling Class to be
@@ -1862,4 +1874,10 @@ void cxgb4_ring_tx_db(struct adapter *adap, struct sge_txq *q, int n);
int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
		    u16 vlan);
int cxgb4_dcb_enabled(const struct net_device *dev);

#ifdef CONFIG_THERMAL
int cxgb4_thermal_init(struct adapter *adap);
int cxgb4_thermal_remove(struct adapter *adap);
#endif /* CONFIG_THERMAL */

#endif /* __CXGB4_H__ */
+8 −0
Original line number Diff line number Diff line
@@ -5864,6 +5864,11 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	if (!is_t4(adapter->params.chip))
		cxgb4_ptp_init(adapter);

#ifdef CONFIG_THERMAL
	if (!is_t4(adapter->params.chip) && (adapter->flags & FW_OK))
		cxgb4_thermal_init(adapter);
#endif /* CONFIG_THERMAL */

	print_adapter_info(adapter);
	return 0;

@@ -5929,6 +5934,9 @@ static void remove_one(struct pci_dev *pdev)

		if (!is_t4(adapter->params.chip))
			cxgb4_ptp_stop(adapter);
#ifdef CONFIG_THERMAL
		cxgb4_thermal_remove(adapter);
#endif

		/* If we allocated filters, free up state associated with any
		 * valid filters ...
+114 −0
Original line number Diff line number Diff line
/*
 *  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;
}
+1 −0
Original line number Diff line number Diff line
@@ -1332,6 +1332,7 @@ enum fw_params_param_dev_phyfw {
enum fw_params_param_dev_diag {
	FW_PARAM_DEV_DIAG_TMP		= 0x00,
	FW_PARAM_DEV_DIAG_VDD		= 0x01,
	FW_PARAM_DEV_DIAG_MAXTMPTHRESH	= 0x02,
};

enum fw_params_param_dev_fwcache {