cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nfp_hwmon.c (3519B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
      2/* Copyright (C) 2017 Netronome Systems, Inc. */
      3
      4#include <linux/kernel.h>
      5#include <linux/bitops.h>
      6#include <linux/hwmon.h>
      7
      8#include "nfpcore/nfp_cpp.h"
      9#include "nfpcore/nfp_nsp.h"
     10#include "nfp_main.h"
     11
     12#define NFP_TEMP_MAX		(95 * 1000)
     13#define NFP_TEMP_CRIT		(105 * 1000)
     14
     15#define NFP_POWER_MAX		(25 * 1000 * 1000)
     16
     17static int nfp_hwmon_sensor_id(enum hwmon_sensor_types type, int channel)
     18{
     19	if (type == hwmon_temp)
     20		return NFP_SENSOR_CHIP_TEMPERATURE;
     21	if (type == hwmon_power)
     22		return NFP_SENSOR_ASSEMBLY_POWER + channel;
     23	return -EINVAL;
     24}
     25
     26static int
     27nfp_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
     28	       int channel, long *val)
     29{
     30	static const struct {
     31		enum hwmon_sensor_types type;
     32		u32 attr;
     33		long val;
     34	} const_vals[] = {
     35		{ hwmon_temp,	hwmon_temp_max,		NFP_TEMP_MAX },
     36		{ hwmon_temp,	hwmon_temp_crit,	NFP_TEMP_CRIT },
     37		{ hwmon_power,	hwmon_power_max,	NFP_POWER_MAX },
     38	};
     39	struct nfp_pf *pf = dev_get_drvdata(dev);
     40	enum nfp_nsp_sensor_id id;
     41	int err, i;
     42
     43	for (i = 0; i < ARRAY_SIZE(const_vals); i++)
     44		if (const_vals[i].type == type && const_vals[i].attr == attr) {
     45			*val = const_vals[i].val;
     46			return 0;
     47		}
     48
     49	err = nfp_hwmon_sensor_id(type, channel);
     50	if (err < 0)
     51		return err;
     52	id = err;
     53
     54	if (!(pf->nspi->sensor_mask & BIT(id)))
     55		return -EOPNOTSUPP;
     56
     57	if (type == hwmon_temp && attr == hwmon_temp_input)
     58		return nfp_hwmon_read_sensor(pf->cpp, id, val);
     59	if (type == hwmon_power && attr == hwmon_power_input)
     60		return nfp_hwmon_read_sensor(pf->cpp, id, val);
     61
     62	return -EINVAL;
     63}
     64
     65static umode_t
     66nfp_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
     67		     int channel)
     68{
     69	if (type == hwmon_temp) {
     70		switch (attr) {
     71		case hwmon_temp_input:
     72		case hwmon_temp_crit:
     73		case hwmon_temp_max:
     74			return 0444;
     75		}
     76	} else if (type == hwmon_power) {
     77		switch (attr) {
     78		case hwmon_power_input:
     79		case hwmon_power_max:
     80			return 0444;
     81		}
     82	}
     83	return 0;
     84}
     85
     86static u32 nfp_chip_config[] = {
     87	HWMON_C_REGISTER_TZ,
     88	0
     89};
     90
     91static const struct hwmon_channel_info nfp_chip = {
     92	.type = hwmon_chip,
     93	.config = nfp_chip_config,
     94};
     95
     96static u32 nfp_temp_config[] = {
     97	HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT,
     98	0
     99};
    100
    101static const struct hwmon_channel_info nfp_temp = {
    102	.type = hwmon_temp,
    103	.config = nfp_temp_config,
    104};
    105
    106static u32 nfp_power_config[] = {
    107	HWMON_P_INPUT | HWMON_P_MAX,
    108	HWMON_P_INPUT,
    109	HWMON_P_INPUT,
    110	0
    111};
    112
    113static const struct hwmon_channel_info nfp_power = {
    114	.type = hwmon_power,
    115	.config = nfp_power_config,
    116};
    117
    118static const struct hwmon_channel_info *nfp_hwmon_info[] = {
    119	&nfp_chip,
    120	&nfp_temp,
    121	&nfp_power,
    122	NULL
    123};
    124
    125static const struct hwmon_ops nfp_hwmon_ops = {
    126	.is_visible = nfp_hwmon_is_visible,
    127	.read = nfp_hwmon_read,
    128};
    129
    130static const struct hwmon_chip_info nfp_chip_info = {
    131	.ops = &nfp_hwmon_ops,
    132	.info = nfp_hwmon_info,
    133};
    134
    135int nfp_hwmon_register(struct nfp_pf *pf)
    136{
    137	if (!IS_REACHABLE(CONFIG_HWMON))
    138		return 0;
    139
    140	if (!pf->nspi) {
    141		nfp_warn(pf->cpp, "not registering HWMON (no NSP info)\n");
    142		return 0;
    143	}
    144	if (!pf->nspi->sensor_mask) {
    145		nfp_info(pf->cpp,
    146			 "not registering HWMON (NSP doesn't report sensors)\n");
    147		return 0;
    148	}
    149
    150	pf->hwmon_dev = hwmon_device_register_with_info(&pf->pdev->dev, "nfp",
    151							pf, &nfp_chip_info,
    152							NULL);
    153	return PTR_ERR_OR_ZERO(pf->hwmon_dev);
    154}
    155
    156void nfp_hwmon_unregister(struct nfp_pf *pf)
    157{
    158	if (!IS_REACHABLE(CONFIG_HWMON) || !pf->hwmon_dev)
    159		return;
    160
    161	hwmon_device_unregister(pf->hwmon_dev);
    162}