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