1 /* $NetBSD: nouveau_hwmon.c,v 1.1.1.2 2014/08/06 12:36:23 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.1.1.2 2014/08/06 12:36:23 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 #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