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

nouveau_hwmon.c (19488B)


      1/*
      2 * Copyright 2010 Red Hat Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: Ben Skeggs
     23 */
     24
     25#ifdef CONFIG_ACPI
     26#include <linux/acpi.h>
     27#endif
     28#include <linux/power_supply.h>
     29#include <linux/hwmon.h>
     30#include <linux/hwmon-sysfs.h>
     31
     32#include "nouveau_drv.h"
     33#include "nouveau_hwmon.h"
     34
     35#include <nvkm/subdev/iccsense.h>
     36#include <nvkm/subdev/volt.h>
     37
     38#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
     39
     40static ssize_t
     41nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
     42					 struct device_attribute *a, char *buf)
     43{
     44	return snprintf(buf, PAGE_SIZE, "%d\n", 100);
     45}
     46static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
     47			  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
     48
     49static ssize_t
     50nouveau_hwmon_temp1_auto_point1_temp(struct device *d,
     51				     struct device_attribute *a, char *buf)
     52{
     53	struct drm_device *dev = dev_get_drvdata(d);
     54	struct nouveau_drm *drm = nouveau_drm(dev);
     55	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
     56
     57	return snprintf(buf, PAGE_SIZE, "%d\n",
     58	      therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000);
     59}
     60static ssize_t
     61nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
     62					 struct device_attribute *a,
     63					 const char *buf, size_t count)
     64{
     65	struct drm_device *dev = dev_get_drvdata(d);
     66	struct nouveau_drm *drm = nouveau_drm(dev);
     67	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
     68	long value;
     69
     70	if (kstrtol(buf, 10, &value))
     71		return -EINVAL;
     72
     73	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST,
     74			value / 1000);
     75
     76	return count;
     77}
     78static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
     79			  nouveau_hwmon_temp1_auto_point1_temp,
     80			  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
     81
     82static ssize_t
     83nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d,
     84					  struct device_attribute *a, char *buf)
     85{
     86	struct drm_device *dev = dev_get_drvdata(d);
     87	struct nouveau_drm *drm = nouveau_drm(dev);
     88	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
     89
     90	return snprintf(buf, PAGE_SIZE, "%d\n",
     91	 therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
     92}
     93static ssize_t
     94nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
     95					      struct device_attribute *a,
     96					      const char *buf, size_t count)
     97{
     98	struct drm_device *dev = dev_get_drvdata(d);
     99	struct nouveau_drm *drm = nouveau_drm(dev);
    100	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    101	long value;
    102
    103	if (kstrtol(buf, 10, &value))
    104		return -EINVAL;
    105
    106	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST,
    107			value / 1000);
    108
    109	return count;
    110}
    111static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
    112			  nouveau_hwmon_temp1_auto_point1_temp_hyst,
    113			  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
    114
    115static ssize_t
    116nouveau_hwmon_get_pwm1_max(struct device *d,
    117			   struct device_attribute *a, char *buf)
    118{
    119	struct drm_device *dev = dev_get_drvdata(d);
    120	struct nouveau_drm *drm = nouveau_drm(dev);
    121	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    122	int ret;
    123
    124	ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY);
    125	if (ret < 0)
    126		return ret;
    127
    128	return sprintf(buf, "%i\n", ret);
    129}
    130
    131static ssize_t
    132nouveau_hwmon_get_pwm1_min(struct device *d,
    133			   struct device_attribute *a, char *buf)
    134{
    135	struct drm_device *dev = dev_get_drvdata(d);
    136	struct nouveau_drm *drm = nouveau_drm(dev);
    137	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    138	int ret;
    139
    140	ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY);
    141	if (ret < 0)
    142		return ret;
    143
    144	return sprintf(buf, "%i\n", ret);
    145}
    146
    147static ssize_t
    148nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
    149			   const char *buf, size_t count)
    150{
    151	struct drm_device *dev = dev_get_drvdata(d);
    152	struct nouveau_drm *drm = nouveau_drm(dev);
    153	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    154	long value;
    155	int ret;
    156
    157	if (kstrtol(buf, 10, &value))
    158		return -EINVAL;
    159
    160	ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY, value);
    161	if (ret < 0)
    162		return ret;
    163
    164	return count;
    165}
    166static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
    167			  nouveau_hwmon_get_pwm1_min,
    168			  nouveau_hwmon_set_pwm1_min, 0);
    169
    170static ssize_t
    171nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
    172			   const char *buf, size_t count)
    173{
    174	struct drm_device *dev = dev_get_drvdata(d);
    175	struct nouveau_drm *drm = nouveau_drm(dev);
    176	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    177	long value;
    178	int ret;
    179
    180	if (kstrtol(buf, 10, &value))
    181		return -EINVAL;
    182
    183	ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY, value);
    184	if (ret < 0)
    185		return ret;
    186
    187	return count;
    188}
    189static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
    190			  nouveau_hwmon_get_pwm1_max,
    191			  nouveau_hwmon_set_pwm1_max, 0);
    192
    193static struct attribute *pwm_fan_sensor_attrs[] = {
    194	&sensor_dev_attr_pwm1_min.dev_attr.attr,
    195	&sensor_dev_attr_pwm1_max.dev_attr.attr,
    196	NULL
    197};
    198static const struct attribute_group pwm_fan_sensor_group = {
    199	.attrs = pwm_fan_sensor_attrs,
    200};
    201
    202static struct attribute *temp1_auto_point_sensor_attrs[] = {
    203	&sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
    204	&sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
    205	&sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
    206	NULL
    207};
    208static const struct attribute_group temp1_auto_point_sensor_group = {
    209	.attrs = temp1_auto_point_sensor_attrs,
    210};
    211
    212#define N_ATTR_GROUPS   3
    213
    214static const u32 nouveau_config_chip[] = {
    215	HWMON_C_UPDATE_INTERVAL,
    216	0
    217};
    218
    219static const u32 nouveau_config_in[] = {
    220	HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
    221	0
    222};
    223
    224static const u32 nouveau_config_temp[] = {
    225	HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
    226	HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
    227	HWMON_T_EMERGENCY_HYST,
    228	0
    229};
    230
    231static const u32 nouveau_config_fan[] = {
    232	HWMON_F_INPUT,
    233	0
    234};
    235
    236static const u32 nouveau_config_pwm[] = {
    237	HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
    238	0
    239};
    240
    241static const u32 nouveau_config_power[] = {
    242	HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
    243	0
    244};
    245
    246static const struct hwmon_channel_info nouveau_chip = {
    247	.type = hwmon_chip,
    248	.config = nouveau_config_chip,
    249};
    250
    251static const struct hwmon_channel_info nouveau_temp = {
    252	.type = hwmon_temp,
    253	.config = nouveau_config_temp,
    254};
    255
    256static const struct hwmon_channel_info nouveau_fan = {
    257	.type = hwmon_fan,
    258	.config = nouveau_config_fan,
    259};
    260
    261static const struct hwmon_channel_info nouveau_in = {
    262	.type = hwmon_in,
    263	.config = nouveau_config_in,
    264};
    265
    266static const struct hwmon_channel_info nouveau_pwm = {
    267	.type = hwmon_pwm,
    268	.config = nouveau_config_pwm,
    269};
    270
    271static const struct hwmon_channel_info nouveau_power = {
    272	.type = hwmon_power,
    273	.config = nouveau_config_power,
    274};
    275
    276static const struct hwmon_channel_info *nouveau_info[] = {
    277	&nouveau_chip,
    278	&nouveau_temp,
    279	&nouveau_fan,
    280	&nouveau_in,
    281	&nouveau_pwm,
    282	&nouveau_power,
    283	NULL
    284};
    285
    286static umode_t
    287nouveau_chip_is_visible(const void *data, u32 attr, int channel)
    288{
    289	switch (attr) {
    290	case hwmon_chip_update_interval:
    291		return 0444;
    292	default:
    293		return 0;
    294	}
    295}
    296
    297static umode_t
    298nouveau_power_is_visible(const void *data, u32 attr, int channel)
    299{
    300	struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
    301	struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
    302
    303	if (!iccsense || !iccsense->data_valid || list_empty(&iccsense->rails))
    304		return 0;
    305
    306	switch (attr) {
    307	case hwmon_power_input:
    308		return 0444;
    309	case hwmon_power_max:
    310		if (iccsense->power_w_max)
    311			return 0444;
    312		return 0;
    313	case hwmon_power_crit:
    314		if (iccsense->power_w_crit)
    315			return 0444;
    316		return 0;
    317	default:
    318		return 0;
    319	}
    320}
    321
    322static umode_t
    323nouveau_temp_is_visible(const void *data, u32 attr, int channel)
    324{
    325	struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
    326	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    327
    328	if (!therm || !therm->attr_get || nvkm_therm_temp_get(therm) < 0)
    329		return 0;
    330
    331	switch (attr) {
    332	case hwmon_temp_input:
    333		return 0444;
    334	case hwmon_temp_max:
    335	case hwmon_temp_max_hyst:
    336	case hwmon_temp_crit:
    337	case hwmon_temp_crit_hyst:
    338	case hwmon_temp_emergency:
    339	case hwmon_temp_emergency_hyst:
    340		return 0644;
    341	default:
    342		return 0;
    343	}
    344}
    345
    346static umode_t
    347nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
    348{
    349	struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
    350	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    351
    352	if (!therm || !therm->attr_get || !therm->fan_get ||
    353	    therm->fan_get(therm) < 0)
    354		return 0;
    355
    356	switch (attr) {
    357	case hwmon_pwm_enable:
    358	case hwmon_pwm_input:
    359		return 0644;
    360	default:
    361		return 0;
    362	}
    363}
    364
    365static umode_t
    366nouveau_input_is_visible(const void *data, u32 attr, int channel)
    367{
    368	struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
    369	struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
    370
    371	if (!volt || nvkm_volt_get(volt) < 0)
    372		return 0;
    373
    374	switch (attr) {
    375	case hwmon_in_input:
    376	case hwmon_in_label:
    377	case hwmon_in_min:
    378	case hwmon_in_max:
    379		return 0444;
    380	default:
    381		return 0;
    382	}
    383}
    384
    385static umode_t
    386nouveau_fan_is_visible(const void *data, u32 attr, int channel)
    387{
    388	struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
    389	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    390
    391	if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
    392		return 0;
    393
    394	switch (attr) {
    395	case hwmon_fan_input:
    396		return 0444;
    397	default:
    398		return 0;
    399	}
    400}
    401
    402static int
    403nouveau_chip_read(struct device *dev, u32 attr, int channel, long *val)
    404{
    405	switch (attr) {
    406	case hwmon_chip_update_interval:
    407		*val = 1000;
    408		break;
    409	default:
    410		return -EOPNOTSUPP;
    411	}
    412
    413	return 0;
    414}
    415
    416static int
    417nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
    418{
    419	struct drm_device *drm_dev = dev_get_drvdata(dev);
    420	struct nouveau_drm *drm = nouveau_drm(drm_dev);
    421	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    422	int ret;
    423
    424	if (!therm || !therm->attr_get)
    425		return -EOPNOTSUPP;
    426
    427	switch (attr) {
    428	case hwmon_temp_input:
    429		if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
    430			return -EINVAL;
    431		ret = nvkm_therm_temp_get(therm);
    432		*val = ret < 0 ? ret : (ret * 1000);
    433		break;
    434	case hwmon_temp_max:
    435		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
    436					* 1000;
    437		break;
    438	case hwmon_temp_max_hyst:
    439		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST)
    440					* 1000;
    441		break;
    442	case hwmon_temp_crit:
    443		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL)
    444					* 1000;
    445		break;
    446	case hwmon_temp_crit_hyst:
    447		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST)
    448					* 1000;
    449		break;
    450	case hwmon_temp_emergency:
    451		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN)
    452					* 1000;
    453		break;
    454	case hwmon_temp_emergency_hyst:
    455		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST)
    456					* 1000;
    457		break;
    458	default:
    459		return -EOPNOTSUPP;
    460	}
    461
    462	return 0;
    463}
    464
    465static int
    466nouveau_fan_read(struct device *dev, u32 attr, int channel, long *val)
    467{
    468	struct drm_device *drm_dev = dev_get_drvdata(dev);
    469	struct nouveau_drm *drm = nouveau_drm(drm_dev);
    470	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    471
    472	if (!therm)
    473		return -EOPNOTSUPP;
    474
    475	switch (attr) {
    476	case hwmon_fan_input:
    477		if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
    478			return -EINVAL;
    479		*val = nvkm_therm_fan_sense(therm);
    480		break;
    481	default:
    482		return -EOPNOTSUPP;
    483	}
    484
    485	return 0;
    486}
    487
    488static int
    489nouveau_in_read(struct device *dev, u32 attr, int channel, long *val)
    490{
    491	struct drm_device *drm_dev = dev_get_drvdata(dev);
    492	struct nouveau_drm *drm = nouveau_drm(drm_dev);
    493	struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
    494	int ret;
    495
    496	if (!volt)
    497		return -EOPNOTSUPP;
    498
    499	switch (attr) {
    500	case hwmon_in_input:
    501		if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
    502			return -EINVAL;
    503		ret = nvkm_volt_get(volt);
    504		*val = ret < 0 ? ret : (ret / 1000);
    505		break;
    506	case hwmon_in_min:
    507		*val = volt->min_uv > 0 ? (volt->min_uv / 1000) : -ENODEV;
    508		break;
    509	case hwmon_in_max:
    510		*val = volt->max_uv > 0 ? (volt->max_uv / 1000) : -ENODEV;
    511		break;
    512	default:
    513		return -EOPNOTSUPP;
    514	}
    515
    516	return 0;
    517}
    518
    519static int
    520nouveau_pwm_read(struct device *dev, u32 attr, int channel, long *val)
    521{
    522	struct drm_device *drm_dev = dev_get_drvdata(dev);
    523	struct nouveau_drm *drm = nouveau_drm(drm_dev);
    524	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    525
    526	if (!therm || !therm->attr_get || !therm->fan_get)
    527		return -EOPNOTSUPP;
    528
    529	switch (attr) {
    530	case hwmon_pwm_enable:
    531		*val = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
    532		break;
    533	case hwmon_pwm_input:
    534		if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
    535			return -EINVAL;
    536		*val = therm->fan_get(therm);
    537		break;
    538	default:
    539		return -EOPNOTSUPP;
    540	}
    541
    542	return 0;
    543}
    544
    545static int
    546nouveau_power_read(struct device *dev, u32 attr, int channel, long *val)
    547{
    548	struct drm_device *drm_dev = dev_get_drvdata(dev);
    549	struct nouveau_drm *drm = nouveau_drm(drm_dev);
    550	struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
    551
    552	if (!iccsense)
    553		return -EOPNOTSUPP;
    554
    555	switch (attr) {
    556	case hwmon_power_input:
    557		if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
    558			return -EINVAL;
    559		*val = nvkm_iccsense_read_all(iccsense);
    560		break;
    561	case hwmon_power_max:
    562		*val = iccsense->power_w_max;
    563		break;
    564	case hwmon_power_crit:
    565		*val = iccsense->power_w_crit;
    566		break;
    567	default:
    568		return -EOPNOTSUPP;
    569	}
    570
    571	return 0;
    572}
    573
    574static int
    575nouveau_temp_write(struct device *dev, u32 attr, int channel, long val)
    576{
    577	struct drm_device *drm_dev = dev_get_drvdata(dev);
    578	struct nouveau_drm *drm = nouveau_drm(drm_dev);
    579	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    580
    581	if (!therm || !therm->attr_set)
    582		return -EOPNOTSUPP;
    583
    584	switch (attr) {
    585	case hwmon_temp_max:
    586		return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK,
    587					val / 1000);
    588	case hwmon_temp_max_hyst:
    589		return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
    590					val / 1000);
    591	case hwmon_temp_crit:
    592		return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL,
    593					val / 1000);
    594	case hwmon_temp_crit_hyst:
    595		return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST,
    596					val / 1000);
    597	case hwmon_temp_emergency:
    598		return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN,
    599					val / 1000);
    600	case hwmon_temp_emergency_hyst:
    601		return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST,
    602					val / 1000);
    603	default:
    604		return -EOPNOTSUPP;
    605	}
    606}
    607
    608static int
    609nouveau_pwm_write(struct device *dev, u32 attr, int channel, long val)
    610{
    611	struct drm_device *drm_dev = dev_get_drvdata(dev);
    612	struct nouveau_drm *drm = nouveau_drm(drm_dev);
    613	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    614
    615	if (!therm || !therm->attr_set)
    616		return -EOPNOTSUPP;
    617
    618	switch (attr) {
    619	case hwmon_pwm_input:
    620		return therm->fan_set(therm, val);
    621	case hwmon_pwm_enable:
    622		return therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, val);
    623	default:
    624		return -EOPNOTSUPP;
    625	}
    626}
    627
    628static umode_t
    629nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
    630			int channel)
    631{
    632	switch (type) {
    633	case hwmon_chip:
    634		return nouveau_chip_is_visible(data, attr, channel);
    635	case hwmon_temp:
    636		return nouveau_temp_is_visible(data, attr, channel);
    637	case hwmon_fan:
    638		return nouveau_fan_is_visible(data, attr, channel);
    639	case hwmon_in:
    640		return nouveau_input_is_visible(data, attr, channel);
    641	case hwmon_pwm:
    642		return nouveau_pwm_is_visible(data, attr, channel);
    643	case hwmon_power:
    644		return nouveau_power_is_visible(data, attr, channel);
    645	default:
    646		return 0;
    647	}
    648}
    649
    650static const char input_label[] = "GPU core";
    651
    652static int
    653nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
    654		    int channel, const char **buf)
    655{
    656	if (type == hwmon_in && attr == hwmon_in_label) {
    657		*buf = input_label;
    658		return 0;
    659	}
    660
    661	return -EOPNOTSUPP;
    662}
    663
    664static int
    665nouveau_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
    666							int channel, long *val)
    667{
    668	switch (type) {
    669	case hwmon_chip:
    670		return nouveau_chip_read(dev, attr, channel, val);
    671	case hwmon_temp:
    672		return nouveau_temp_read(dev, attr, channel, val);
    673	case hwmon_fan:
    674		return nouveau_fan_read(dev, attr, channel, val);
    675	case hwmon_in:
    676		return nouveau_in_read(dev, attr, channel, val);
    677	case hwmon_pwm:
    678		return nouveau_pwm_read(dev, attr, channel, val);
    679	case hwmon_power:
    680		return nouveau_power_read(dev, attr, channel, val);
    681	default:
    682		return -EOPNOTSUPP;
    683	}
    684}
    685
    686static int
    687nouveau_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
    688							int channel, long val)
    689{
    690	switch (type) {
    691	case hwmon_temp:
    692		return nouveau_temp_write(dev, attr, channel, val);
    693	case hwmon_pwm:
    694		return nouveau_pwm_write(dev, attr, channel, val);
    695	default:
    696		return -EOPNOTSUPP;
    697	}
    698}
    699
    700static const struct hwmon_ops nouveau_hwmon_ops = {
    701	.is_visible = nouveau_is_visible,
    702	.read = nouveau_read,
    703	.read_string = nouveau_read_string,
    704	.write = nouveau_write,
    705};
    706
    707static const struct hwmon_chip_info nouveau_chip_info = {
    708	.ops = &nouveau_hwmon_ops,
    709	.info = nouveau_info,
    710};
    711#endif
    712
    713int
    714nouveau_hwmon_init(struct drm_device *dev)
    715{
    716#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
    717	struct nouveau_drm *drm = nouveau_drm(dev);
    718	struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
    719	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
    720	struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
    721	const struct attribute_group *special_groups[N_ATTR_GROUPS];
    722	struct nouveau_hwmon *hwmon;
    723	struct device *hwmon_dev;
    724	int ret = 0;
    725	int i = 0;
    726
    727	if (!iccsense && !therm && !volt) {
    728		NV_DEBUG(drm, "Skipping hwmon registration\n");
    729		return 0;
    730	}
    731
    732	hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
    733	if (!hwmon)
    734		return -ENOMEM;
    735	hwmon->dev = dev;
    736
    737	if (therm && therm->attr_get && therm->attr_set) {
    738		if (nvkm_therm_temp_get(therm) >= 0)
    739			special_groups[i++] = &temp1_auto_point_sensor_group;
    740		if (therm->fan_get && therm->fan_get(therm) >= 0)
    741			special_groups[i++] = &pwm_fan_sensor_group;
    742	}
    743
    744	special_groups[i] = NULL;
    745	hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
    746							&nouveau_chip_info,
    747							special_groups);
    748	if (IS_ERR(hwmon_dev)) {
    749		ret = PTR_ERR(hwmon_dev);
    750		NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
    751		return ret;
    752	}
    753
    754	hwmon->hwmon = hwmon_dev;
    755	return 0;
    756#else
    757	return 0;
    758#endif
    759}
    760
    761void
    762nouveau_hwmon_fini(struct drm_device *dev)
    763{
    764#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
    765	struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
    766
    767	if (!hwmon)
    768		return;
    769
    770	if (hwmon->hwmon)
    771		hwmon_device_unregister(hwmon->hwmon);
    772
    773	nouveau_drm(dev)->hwmon = NULL;
    774	kfree(hwmon);
    775#endif
    776}