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