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