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