root/drivers/net/ethernet/netronome/nfp/nfp_hwmon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nfp_hwmon_sensor_id
  2. nfp_hwmon_read
  3. nfp_hwmon_is_visible
  4. nfp_hwmon_register
  5. nfp_hwmon_unregister

   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 
  17 static 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 
  26 static int
  27 nfp_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 
  65 static umode_t
  66 nfp_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 
  86 static u32 nfp_chip_config[] = {
  87         HWMON_C_REGISTER_TZ,
  88         0
  89 };
  90 
  91 static const struct hwmon_channel_info nfp_chip = {
  92         .type = hwmon_chip,
  93         .config = nfp_chip_config,
  94 };
  95 
  96 static u32 nfp_temp_config[] = {
  97         HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT,
  98         0
  99 };
 100 
 101 static const struct hwmon_channel_info nfp_temp = {
 102         .type = hwmon_temp,
 103         .config = nfp_temp_config,
 104 };
 105 
 106 static u32 nfp_power_config[] = {
 107         HWMON_P_INPUT | HWMON_P_MAX,
 108         HWMON_P_INPUT,
 109         HWMON_P_INPUT,
 110         0
 111 };
 112 
 113 static const struct hwmon_channel_info nfp_power = {
 114         .type = hwmon_power,
 115         .config = nfp_power_config,
 116 };
 117 
 118 static const struct hwmon_channel_info *nfp_hwmon_info[] = {
 119         &nfp_chip,
 120         &nfp_temp,
 121         &nfp_power,
 122         NULL
 123 };
 124 
 125 static const struct hwmon_ops nfp_hwmon_ops = {
 126         .is_visible = nfp_hwmon_is_visible,
 127         .read = nfp_hwmon_read,
 128 };
 129 
 130 static const struct hwmon_chip_info nfp_chip_info = {
 131         .ops = &nfp_hwmon_ops,
 132         .info = nfp_hwmon_info,
 133 };
 134 
 135 int 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 
 156 void 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 }

/* [<][>][^][v][top][bottom][index][help] */