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