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