Home | History | Annotate | Line # | Download | only in nouveau
nouveau_hwmon.c revision 1.2
      1 /*	$NetBSD: nouveau_hwmon.c,v 1.2 2018/08/27 04:58:24 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.2 2018/08/27 04:58:24 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 <drm/drmP.h>
     38 
     39 #include "nouveau_drm.h"
     40 #include "nouveau_hwmon.h"
     41 
     42 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
     43 static ssize_t
     44 nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
     45 {
     46 	struct drm_device *dev = dev_get_drvdata(d);
     47 	struct nouveau_drm *drm = nouveau_drm(dev);
     48 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
     49 	int temp = nvkm_therm_temp_get(therm);
     50 
     51 	if (temp < 0)
     52 		return temp;
     53 
     54 	return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
     55 }
     56 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
     57 						  NULL, 0);
     58 
     59 static ssize_t
     60 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
     61 					 struct device_attribute *a, char *buf)
     62 {
     63 	return snprintf(buf, PAGE_SIZE, "%d\n", 100);
     64 }
     65 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
     66 			  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
     67 
     68 static ssize_t
     69 nouveau_hwmon_temp1_auto_point1_temp(struct device *d,
     70 				     struct device_attribute *a, char *buf)
     71 {
     72 	struct drm_device *dev = dev_get_drvdata(d);
     73 	struct nouveau_drm *drm = nouveau_drm(dev);
     74 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
     75 
     76 	return snprintf(buf, PAGE_SIZE, "%d\n",
     77 	      therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000);
     78 }
     79 static ssize_t
     80 nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
     81 					 struct device_attribute *a,
     82 					 const char *buf, size_t count)
     83 {
     84 	struct drm_device *dev = dev_get_drvdata(d);
     85 	struct nouveau_drm *drm = nouveau_drm(dev);
     86 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
     87 	long value;
     88 
     89 	if (kstrtol(buf, 10, &value) == -EINVAL)
     90 		return count;
     91 
     92 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST,
     93 			value / 1000);
     94 
     95 	return count;
     96 }
     97 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
     98 			  nouveau_hwmon_temp1_auto_point1_temp,
     99 			  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
    100 
    101 static ssize_t
    102 nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d,
    103 					  struct device_attribute *a, char *buf)
    104 {
    105 	struct drm_device *dev = dev_get_drvdata(d);
    106 	struct nouveau_drm *drm = nouveau_drm(dev);
    107 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    108 
    109 	return snprintf(buf, PAGE_SIZE, "%d\n",
    110 	 therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
    111 }
    112 static ssize_t
    113 nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
    114 					      struct device_attribute *a,
    115 					      const char *buf, size_t count)
    116 {
    117 	struct drm_device *dev = dev_get_drvdata(d);
    118 	struct nouveau_drm *drm = nouveau_drm(dev);
    119 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    120 	long value;
    121 
    122 	if (kstrtol(buf, 10, &value) == -EINVAL)
    123 		return count;
    124 
    125 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST,
    126 			value / 1000);
    127 
    128 	return count;
    129 }
    130 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
    131 			  nouveau_hwmon_temp1_auto_point1_temp_hyst,
    132 			  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
    133 
    134 static ssize_t
    135 nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
    136 {
    137 	struct drm_device *dev = dev_get_drvdata(d);
    138 	struct nouveau_drm *drm = nouveau_drm(dev);
    139 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    140 
    141 	return snprintf(buf, PAGE_SIZE, "%d\n",
    142 	       therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
    143 }
    144 static ssize_t
    145 nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
    146 						const char *buf, size_t count)
    147 {
    148 	struct drm_device *dev = dev_get_drvdata(d);
    149 	struct nouveau_drm *drm = nouveau_drm(dev);
    150 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    151 	long value;
    152 
    153 	if (kstrtol(buf, 10, &value) == -EINVAL)
    154 		return count;
    155 
    156 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
    157 
    158 	return count;
    159 }
    160 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
    161 						  nouveau_hwmon_set_max_temp,
    162 						  0);
    163 
    164 static ssize_t
    165 nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
    166 			    char *buf)
    167 {
    168 	struct drm_device *dev = dev_get_drvdata(d);
    169 	struct nouveau_drm *drm = nouveau_drm(dev);
    170 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    171 
    172 	return snprintf(buf, PAGE_SIZE, "%d\n",
    173 	  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
    174 }
    175 static ssize_t
    176 nouveau_hwmon_set_max_temp_hyst(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->device);
    182 	long value;
    183 
    184 	if (kstrtol(buf, 10, &value) == -EINVAL)
    185 		return count;
    186 
    187 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
    188 			value / 1000);
    189 
    190 	return count;
    191 }
    192 static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
    193 			  nouveau_hwmon_max_temp_hyst,
    194 			  nouveau_hwmon_set_max_temp_hyst, 0);
    195 
    196 static ssize_t
    197 nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
    198 							char *buf)
    199 {
    200 	struct drm_device *dev = dev_get_drvdata(d);
    201 	struct nouveau_drm *drm = nouveau_drm(dev);
    202 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    203 
    204 	return snprintf(buf, PAGE_SIZE, "%d\n",
    205 	       therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
    206 }
    207 static ssize_t
    208 nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
    209 							    const char *buf,
    210 								size_t count)
    211 {
    212 	struct drm_device *dev = dev_get_drvdata(d);
    213 	struct nouveau_drm *drm = nouveau_drm(dev);
    214 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    215 	long value;
    216 
    217 	if (kstrtol(buf, 10, &value) == -EINVAL)
    218 		return count;
    219 
    220 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL, value / 1000);
    221 
    222 	return count;
    223 }
    224 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR,
    225 						nouveau_hwmon_critical_temp,
    226 						nouveau_hwmon_set_critical_temp,
    227 						0);
    228 
    229 static ssize_t
    230 nouveau_hwmon_critical_temp_hyst(struct device *d, struct device_attribute *a,
    231 							char *buf)
    232 {
    233 	struct drm_device *dev = dev_get_drvdata(d);
    234 	struct nouveau_drm *drm = nouveau_drm(dev);
    235 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    236 
    237 	return snprintf(buf, PAGE_SIZE, "%d\n",
    238 	  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST) * 1000);
    239 }
    240 static ssize_t
    241 nouveau_hwmon_set_critical_temp_hyst(struct device *d,
    242 				     struct device_attribute *a,
    243 				     const char *buf,
    244 				     size_t count)
    245 {
    246 	struct drm_device *dev = dev_get_drvdata(d);
    247 	struct nouveau_drm *drm = nouveau_drm(dev);
    248 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    249 	long value;
    250 
    251 	if (kstrtol(buf, 10, &value) == -EINVAL)
    252 		return count;
    253 
    254 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST,
    255 			value / 1000);
    256 
    257 	return count;
    258 }
    259 static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR,
    260 			  nouveau_hwmon_critical_temp_hyst,
    261 			  nouveau_hwmon_set_critical_temp_hyst, 0);
    262 static ssize_t
    263 nouveau_hwmon_emergency_temp(struct device *d, struct device_attribute *a,
    264 							char *buf)
    265 {
    266 	struct drm_device *dev = dev_get_drvdata(d);
    267 	struct nouveau_drm *drm = nouveau_drm(dev);
    268 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    269 
    270 	return snprintf(buf, PAGE_SIZE, "%d\n",
    271 	       therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN) * 1000);
    272 }
    273 static ssize_t
    274 nouveau_hwmon_set_emergency_temp(struct device *d, struct device_attribute *a,
    275 							    const char *buf,
    276 								size_t count)
    277 {
    278 	struct drm_device *dev = dev_get_drvdata(d);
    279 	struct nouveau_drm *drm = nouveau_drm(dev);
    280 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    281 	long value;
    282 
    283 	if (kstrtol(buf, 10, &value) == -EINVAL)
    284 		return count;
    285 
    286 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN, value / 1000);
    287 
    288 	return count;
    289 }
    290 static SENSOR_DEVICE_ATTR(temp1_emergency, S_IRUGO | S_IWUSR,
    291 					nouveau_hwmon_emergency_temp,
    292 					nouveau_hwmon_set_emergency_temp,
    293 					0);
    294 
    295 static ssize_t
    296 nouveau_hwmon_emergency_temp_hyst(struct device *d, struct device_attribute *a,
    297 							char *buf)
    298 {
    299 	struct drm_device *dev = dev_get_drvdata(d);
    300 	struct nouveau_drm *drm = nouveau_drm(dev);
    301 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    302 
    303 	return snprintf(buf, PAGE_SIZE, "%d\n",
    304 	  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST) * 1000);
    305 }
    306 static ssize_t
    307 nouveau_hwmon_set_emergency_temp_hyst(struct device *d,
    308 				      struct device_attribute *a,
    309 				      const char *buf,
    310 				      size_t count)
    311 {
    312 	struct drm_device *dev = dev_get_drvdata(d);
    313 	struct nouveau_drm *drm = nouveau_drm(dev);
    314 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    315 	long value;
    316 
    317 	if (kstrtol(buf, 10, &value) == -EINVAL)
    318 		return count;
    319 
    320 	therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST,
    321 			value / 1000);
    322 
    323 	return count;
    324 }
    325 static SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO | S_IWUSR,
    326 					nouveau_hwmon_emergency_temp_hyst,
    327 					nouveau_hwmon_set_emergency_temp_hyst,
    328 					0);
    329 
    330 static ssize_t nouveau_hwmon_show_name(struct device *dev,
    331 				      struct device_attribute *attr,
    332 				      char *buf)
    333 {
    334 	return sprintf(buf, "nouveau\n");
    335 }
    336 static SENSOR_DEVICE_ATTR(name, S_IRUGO, nouveau_hwmon_show_name, NULL, 0);
    337 
    338 static ssize_t nouveau_hwmon_show_update_rate(struct device *dev,
    339 				      struct device_attribute *attr,
    340 				      char *buf)
    341 {
    342 	return sprintf(buf, "1000\n");
    343 }
    344 static SENSOR_DEVICE_ATTR(update_rate, S_IRUGO,
    345 						nouveau_hwmon_show_update_rate,
    346 						NULL, 0);
    347 
    348 static ssize_t
    349 nouveau_hwmon_show_fan1_input(struct device *d, struct device_attribute *attr,
    350 			      char *buf)
    351 {
    352 	struct drm_device *dev = dev_get_drvdata(d);
    353 	struct nouveau_drm *drm = nouveau_drm(dev);
    354 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    355 
    356 	return snprintf(buf, PAGE_SIZE, "%d\n", nvkm_therm_fan_sense(therm));
    357 }
    358 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, nouveau_hwmon_show_fan1_input,
    359 			  NULL, 0);
    360 
    361  static ssize_t
    362 nouveau_hwmon_get_pwm1_enable(struct device *d,
    363 			   struct device_attribute *a, char *buf)
    364 {
    365 	struct drm_device *dev = dev_get_drvdata(d);
    366 	struct nouveau_drm *drm = nouveau_drm(dev);
    367 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    368 	int ret;
    369 
    370 	ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
    371 	if (ret < 0)
    372 		return ret;
    373 
    374 	return sprintf(buf, "%i\n", ret);
    375 }
    376 
    377 static ssize_t
    378 nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a,
    379 			   const char *buf, size_t count)
    380 {
    381 	struct drm_device *dev = dev_get_drvdata(d);
    382 	struct nouveau_drm *drm = nouveau_drm(dev);
    383 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    384 	long value;
    385 	int ret;
    386 
    387 	ret = kstrtol(buf, 10, &value);
    388 	if (ret)
    389 		return ret;
    390 
    391 	ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, value);
    392 	if (ret)
    393 		return ret;
    394 	else
    395 		return count;
    396 }
    397 static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
    398 			  nouveau_hwmon_get_pwm1_enable,
    399 			  nouveau_hwmon_set_pwm1_enable, 0);
    400 
    401 static ssize_t
    402 nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf)
    403 {
    404 	struct drm_device *dev = dev_get_drvdata(d);
    405 	struct nouveau_drm *drm = nouveau_drm(dev);
    406 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    407 	int ret;
    408 
    409 	ret = therm->fan_get(therm);
    410 	if (ret < 0)
    411 		return ret;
    412 
    413 	return sprintf(buf, "%i\n", ret);
    414 }
    415 
    416 static ssize_t
    417 nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a,
    418 		       const char *buf, size_t count)
    419 {
    420 	struct drm_device *dev = dev_get_drvdata(d);
    421 	struct nouveau_drm *drm = nouveau_drm(dev);
    422 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    423 	int ret = -ENODEV;
    424 	long value;
    425 
    426 	if (kstrtol(buf, 10, &value) == -EINVAL)
    427 		return -EINVAL;
    428 
    429 	ret = therm->fan_set(therm, value);
    430 	if (ret)
    431 		return ret;
    432 
    433 	return count;
    434 }
    435 
    436 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR,
    437 			  nouveau_hwmon_get_pwm1,
    438 			  nouveau_hwmon_set_pwm1, 0);
    439 
    440 static ssize_t
    441 nouveau_hwmon_get_pwm1_min(struct device *d,
    442 			   struct device_attribute *a, char *buf)
    443 {
    444 	struct drm_device *dev = dev_get_drvdata(d);
    445 	struct nouveau_drm *drm = nouveau_drm(dev);
    446 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    447 	int ret;
    448 
    449 	ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY);
    450 	if (ret < 0)
    451 		return ret;
    452 
    453 	return sprintf(buf, "%i\n", ret);
    454 }
    455 
    456 static ssize_t
    457 nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
    458 			   const char *buf, size_t count)
    459 {
    460 	struct drm_device *dev = dev_get_drvdata(d);
    461 	struct nouveau_drm *drm = nouveau_drm(dev);
    462 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    463 	long value;
    464 	int ret;
    465 
    466 	if (kstrtol(buf, 10, &value) == -EINVAL)
    467 		return -EINVAL;
    468 
    469 	ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY, value);
    470 	if (ret < 0)
    471 		return ret;
    472 
    473 	return count;
    474 }
    475 
    476 static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
    477 			  nouveau_hwmon_get_pwm1_min,
    478 			  nouveau_hwmon_set_pwm1_min, 0);
    479 
    480 static ssize_t
    481 nouveau_hwmon_get_pwm1_max(struct device *d,
    482 			   struct device_attribute *a, char *buf)
    483 {
    484 	struct drm_device *dev = dev_get_drvdata(d);
    485 	struct nouveau_drm *drm = nouveau_drm(dev);
    486 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    487 	int ret;
    488 
    489 	ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY);
    490 	if (ret < 0)
    491 		return ret;
    492 
    493 	return sprintf(buf, "%i\n", ret);
    494 }
    495 
    496 static ssize_t
    497 nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
    498 			   const char *buf, size_t count)
    499 {
    500 	struct drm_device *dev = dev_get_drvdata(d);
    501 	struct nouveau_drm *drm = nouveau_drm(dev);
    502 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    503 	long value;
    504 	int ret;
    505 
    506 	if (kstrtol(buf, 10, &value) == -EINVAL)
    507 		return -EINVAL;
    508 
    509 	ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY, value);
    510 	if (ret < 0)
    511 		return ret;
    512 
    513 	return count;
    514 }
    515 
    516 static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
    517 			  nouveau_hwmon_get_pwm1_max,
    518 			  nouveau_hwmon_set_pwm1_max, 0);
    519 
    520 static struct attribute *hwmon_default_attributes[] = {
    521 	&sensor_dev_attr_name.dev_attr.attr,
    522 	&sensor_dev_attr_update_rate.dev_attr.attr,
    523 	NULL
    524 };
    525 static struct attribute *hwmon_temp_attributes[] = {
    526 	&sensor_dev_attr_temp1_input.dev_attr.attr,
    527 	&sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
    528 	&sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
    529 	&sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
    530 	&sensor_dev_attr_temp1_max.dev_attr.attr,
    531 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
    532 	&sensor_dev_attr_temp1_crit.dev_attr.attr,
    533 	&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
    534 	&sensor_dev_attr_temp1_emergency.dev_attr.attr,
    535 	&sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr,
    536 	NULL
    537 };
    538 static struct attribute *hwmon_fan_rpm_attributes[] = {
    539 	&sensor_dev_attr_fan1_input.dev_attr.attr,
    540 	NULL
    541 };
    542 static struct attribute *hwmon_pwm_fan_attributes[] = {
    543 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
    544 	&sensor_dev_attr_pwm1.dev_attr.attr,
    545 	&sensor_dev_attr_pwm1_min.dev_attr.attr,
    546 	&sensor_dev_attr_pwm1_max.dev_attr.attr,
    547 	NULL
    548 };
    549 
    550 static const struct attribute_group hwmon_default_attrgroup = {
    551 	.attrs = hwmon_default_attributes,
    552 };
    553 static const struct attribute_group hwmon_temp_attrgroup = {
    554 	.attrs = hwmon_temp_attributes,
    555 };
    556 static const struct attribute_group hwmon_fan_rpm_attrgroup = {
    557 	.attrs = hwmon_fan_rpm_attributes,
    558 };
    559 static const struct attribute_group hwmon_pwm_fan_attrgroup = {
    560 	.attrs = hwmon_pwm_fan_attributes,
    561 };
    562 #endif
    563 
    564 int
    565 nouveau_hwmon_init(struct drm_device *dev)
    566 {
    567 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
    568 	struct nouveau_drm *drm = nouveau_drm(dev);
    569 	struct nvkm_therm *therm = nvxx_therm(&drm->device);
    570 	struct nouveau_hwmon *hwmon;
    571 	struct device *hwmon_dev;
    572 	int ret = 0;
    573 
    574 	hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
    575 	if (!hwmon)
    576 		return -ENOMEM;
    577 	hwmon->dev = dev;
    578 
    579 	if (!therm || !therm->attr_get || !therm->attr_set)
    580 		return -ENODEV;
    581 
    582 	hwmon_dev = hwmon_device_register(&dev->pdev->dev);
    583 	if (IS_ERR(hwmon_dev)) {
    584 		ret = PTR_ERR(hwmon_dev);
    585 		NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
    586 		return ret;
    587 	}
    588 	dev_set_drvdata(hwmon_dev, dev);
    589 
    590 	/* set the default attributes */
    591 	ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_default_attrgroup);
    592 	if (ret)
    593 		goto error;
    594 
    595 	/* if the card has a working thermal sensor */
    596 	if (nvkm_therm_temp_get(therm) >= 0) {
    597 		ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup);
    598 		if (ret)
    599 			goto error;
    600 	}
    601 
    602 	/* if the card has a pwm fan */
    603 	/*XXX: incorrect, need better detection for this, some boards have
    604 	 *     the gpio entries for pwm fan control even when there's no
    605 	 *     actual fan connected to it... therm table? */
    606 	if (therm->fan_get && therm->fan_get(therm) >= 0) {
    607 		ret = sysfs_create_group(&hwmon_dev->kobj,
    608 					 &hwmon_pwm_fan_attrgroup);
    609 		if (ret)
    610 			goto error;
    611 	}
    612 
    613 	/* if the card can read the fan rpm */
    614 	if (nvkm_therm_fan_sense(therm) >= 0) {
    615 		ret = sysfs_create_group(&hwmon_dev->kobj,
    616 					 &hwmon_fan_rpm_attrgroup);
    617 		if (ret)
    618 			goto error;
    619 	}
    620 
    621 	hwmon->hwmon = hwmon_dev;
    622 
    623 	return 0;
    624 
    625 error:
    626 	NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret);
    627 	hwmon_device_unregister(hwmon_dev);
    628 	hwmon->hwmon = NULL;
    629 	return ret;
    630 #else
    631 	return 0;
    632 #endif
    633 }
    634 
    635 void
    636 nouveau_hwmon_fini(struct drm_device *dev)
    637 {
    638 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
    639 	struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
    640 
    641 	if (hwmon->hwmon) {
    642 		sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_default_attrgroup);
    643 		sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_temp_attrgroup);
    644 		sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_pwm_fan_attrgroup);
    645 		sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_fan_rpm_attrgroup);
    646 
    647 		hwmon_device_unregister(hwmon->hwmon);
    648 	}
    649 
    650 	nouveau_drm(dev)->hwmon = NULL;
    651 	kfree(hwmon);
    652 #endif
    653 }
    654