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