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 42 static ssize_t 43 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d, 44 struct device_attribute *a, char *buf) 45 { 46 return snprintf(buf, PAGE_SIZE, "%d\n", 100); 47 } 48 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444, 49 nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0); 50 51 static ssize_t 52 nouveau_hwmon_temp1_auto_point1_temp(struct device *d, 53 struct device_attribute *a, char *buf) 54 { 55 struct drm_device *dev = dev_get_drvdata(d); 56 struct nouveau_drm *drm = nouveau_drm(dev); 57 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 58 59 return snprintf(buf, PAGE_SIZE, "%d\n", 60 therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000); 61 } 62 static ssize_t 63 nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d, 64 struct device_attribute *a, 65 const char *buf, size_t count) 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->client.device); 70 long value; 71 72 if (kstrtol(buf, 10, &value)) 73 return -EINVAL; 74 75 therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST, 76 value / 1000); 77 78 return count; 79 } 80 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644, 81 nouveau_hwmon_temp1_auto_point1_temp, 82 nouveau_hwmon_set_temp1_auto_point1_temp, 0); 83 84 static ssize_t 85 nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d, 86 struct device_attribute *a, char *buf) 87 { 88 struct drm_device *dev = dev_get_drvdata(d); 89 struct nouveau_drm *drm = nouveau_drm(dev); 90 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 91 92 return snprintf(buf, PAGE_SIZE, "%d\n", 93 therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000); 94 } 95 static ssize_t 96 nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d, 97 struct device_attribute *a, 98 const char *buf, size_t count) 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->client.device); 103 long value; 104 105 if (kstrtol(buf, 10, &value)) 106 return -EINVAL; 107 108 therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST, 109 value / 1000); 110 111 return count; 112 } 113 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644, 114 nouveau_hwmon_temp1_auto_point1_temp_hyst, 115 nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0); 116 117 static ssize_t 118 nouveau_hwmon_get_pwm1_max(struct device *d, 119 struct device_attribute *a, char *buf) 120 { 121 struct drm_device *dev = dev_get_drvdata(d); 122 struct nouveau_drm *drm = nouveau_drm(dev); 123 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 124 int ret; 125 126 ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY); 127 if (ret < 0) 128 return ret; 129 130 return sprintf(buf, "%i\n", ret); 131 } 132 133 static ssize_t 134 nouveau_hwmon_get_pwm1_min(struct device *d, 135 struct device_attribute *a, char *buf) 136 { 137 struct drm_device *dev = dev_get_drvdata(d); 138 struct nouveau_drm *drm = nouveau_drm(dev); 139 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 140 int ret; 141 142 ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY); 143 if (ret < 0) 144 return ret; 145 146 return sprintf(buf, "%i\n", ret); 147 } 148 149 static ssize_t 150 nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a, 151 const char *buf, size_t count) 152 { 153 struct drm_device *dev = dev_get_drvdata(d); 154 struct nouveau_drm *drm = nouveau_drm(dev); 155 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 156 long value; 157 int ret; 158 159 if (kstrtol(buf, 10, &value)) 160 return -EINVAL; 161 162 ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY, value); 163 if (ret < 0) 164 return ret; 165 166 return count; 167 } 168 static SENSOR_DEVICE_ATTR(pwm1_min, 0644, 169 nouveau_hwmon_get_pwm1_min, 170 nouveau_hwmon_set_pwm1_min, 0); 171 172 static ssize_t 173 nouveau_hwmon_set_pwm1_max(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->client.device); 179 long value; 180 int ret; 181 182 if (kstrtol(buf, 10, &value)) 183 return -EINVAL; 184 185 ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY, value); 186 if (ret < 0) 187 return ret; 188 189 return count; 190 } 191 static SENSOR_DEVICE_ATTR(pwm1_max, 0644, 192 nouveau_hwmon_get_pwm1_max, 193 nouveau_hwmon_set_pwm1_max, 0); 194 195 static struct attribute *pwm_fan_sensor_attrs[] = { 196 &sensor_dev_attr_pwm1_min.dev_attr.attr, 197 &sensor_dev_attr_pwm1_max.dev_attr.attr, 198 NULL 199 }; 200 static const struct attribute_group pwm_fan_sensor_group = { 201 .attrs = pwm_fan_sensor_attrs, 202 }; 203 204 static struct attribute *temp1_auto_point_sensor_attrs[] = { 205 &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr, 206 &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, 207 &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr, 208 NULL 209 }; 210 static const struct attribute_group temp1_auto_point_sensor_group = { 211 .attrs = temp1_auto_point_sensor_attrs, 212 }; 213 214 #define N_ATTR_GROUPS 3 215 216 static const u32 nouveau_config_chip[] = { 217 HWMON_C_UPDATE_INTERVAL, 218 0 219 }; 220 221 static const u32 nouveau_config_in[] = { 222 HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL, 223 0 224 }; 225 226 static const u32 nouveau_config_temp[] = { 227 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | 228 HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY | 229 HWMON_T_EMERGENCY_HYST, 230 0 231 }; 232 233 static const u32 nouveau_config_fan[] = { 234 HWMON_F_INPUT, 235 0 236 }; 237 238 static const u32 nouveau_config_pwm[] = { 239 HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 240 0 241 }; 242 243 static const u32 nouveau_config_power[] = { 244 HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT, 245 0 246 }; 247 248 static const struct hwmon_channel_info nouveau_chip = { 249 .type = hwmon_chip, 250 .config = nouveau_config_chip, 251 }; 252 253 static const struct hwmon_channel_info nouveau_temp = { 254 .type = hwmon_temp, 255 .config = nouveau_config_temp, 256 }; 257 258 static const struct hwmon_channel_info nouveau_fan = { 259 .type = hwmon_fan, 260 .config = nouveau_config_fan, 261 }; 262 263 static const struct hwmon_channel_info nouveau_in = { 264 .type = hwmon_in, 265 .config = nouveau_config_in, 266 }; 267 268 static const struct hwmon_channel_info nouveau_pwm = { 269 .type = hwmon_pwm, 270 .config = nouveau_config_pwm, 271 }; 272 273 static const struct hwmon_channel_info nouveau_power = { 274 .type = hwmon_power, 275 .config = nouveau_config_power, 276 }; 277 278 static const struct hwmon_channel_info *nouveau_info[] = { 279 &nouveau_chip, 280 &nouveau_temp, 281 &nouveau_fan, 282 &nouveau_in, 283 &nouveau_pwm, 284 &nouveau_power, 285 NULL 286 }; 287 288 static umode_t 289 nouveau_chip_is_visible(const void *data, u32 attr, int channel) 290 { 291 switch (attr) { 292 case hwmon_chip_update_interval: 293 return 0444; 294 default: 295 return 0; 296 } 297 } 298 299 static umode_t 300 nouveau_power_is_visible(const void *data, u32 attr, int channel) 301 { 302 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); 303 struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device); 304 305 if (!iccsense || !iccsense->data_valid || list_empty(&iccsense->rails)) 306 return 0; 307 308 switch (attr) { 309 case hwmon_power_input: 310 return 0444; 311 case hwmon_power_max: 312 if (iccsense->power_w_max) 313 return 0444; 314 return 0; 315 case hwmon_power_crit: 316 if (iccsense->power_w_crit) 317 return 0444; 318 return 0; 319 default: 320 return 0; 321 } 322 } 323 324 static umode_t 325 nouveau_temp_is_visible(const void *data, u32 attr, int channel) 326 { 327 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); 328 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 329 330 if (!therm || !therm->attr_get || nvkm_therm_temp_get(therm) < 0) 331 return 0; 332 333 switch (attr) { 334 case hwmon_temp_input: 335 return 0444; 336 case hwmon_temp_max: 337 case hwmon_temp_max_hyst: 338 case hwmon_temp_crit: 339 case hwmon_temp_crit_hyst: 340 case hwmon_temp_emergency: 341 case hwmon_temp_emergency_hyst: 342 return 0644; 343 default: 344 return 0; 345 } 346 } 347 348 static umode_t 349 nouveau_pwm_is_visible(const void *data, u32 attr, int channel) 350 { 351 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); 352 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 353 354 if (!therm || !therm->attr_get || !therm->fan_get || 355 therm->fan_get(therm) < 0) 356 return 0; 357 358 switch (attr) { 359 case hwmon_pwm_enable: 360 case hwmon_pwm_input: 361 return 0644; 362 default: 363 return 0; 364 } 365 } 366 367 static umode_t 368 nouveau_input_is_visible(const void *data, u32 attr, int channel) 369 { 370 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); 371 struct nvkm_volt *volt = nvxx_volt(&drm->client.device); 372 373 if (!volt || nvkm_volt_get(volt) < 0) 374 return 0; 375 376 switch (attr) { 377 case hwmon_in_input: 378 case hwmon_in_label: 379 case hwmon_in_min: 380 case hwmon_in_max: 381 return 0444; 382 default: 383 return 0; 384 } 385 } 386 387 static umode_t 388 nouveau_fan_is_visible(const void *data, u32 attr, int channel) 389 { 390 struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); 391 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 392 393 if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0) 394 return 0; 395 396 switch (attr) { 397 case hwmon_fan_input: 398 return 0444; 399 default: 400 return 0; 401 } 402 } 403 404 static int 405 nouveau_chip_read(struct device *dev, u32 attr, int channel, long *val) 406 { 407 switch (attr) { 408 case hwmon_chip_update_interval: 409 *val = 1000; 410 break; 411 default: 412 return -EOPNOTSUPP; 413 } 414 415 return 0; 416 } 417 418 static int 419 nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val) 420 { 421 struct drm_device *drm_dev = dev_get_drvdata(dev); 422 struct nouveau_drm *drm = nouveau_drm(drm_dev); 423 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 424 int ret; 425 426 if (!therm || !therm->attr_get) 427 return -EOPNOTSUPP; 428 429 switch (attr) { 430 case hwmon_temp_input: 431 ret = nvkm_therm_temp_get(therm); 432 *val = ret < 0 ? ret : (ret * 1000); 433 break; 434 case hwmon_temp_max: 435 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) 436 * 1000; 437 break; 438 case hwmon_temp_max_hyst: 439 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) 440 * 1000; 441 break; 442 case hwmon_temp_crit: 443 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) 444 * 1000; 445 break; 446 case hwmon_temp_crit_hyst: 447 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST) 448 * 1000; 449 break; 450 case hwmon_temp_emergency: 451 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN) 452 * 1000; 453 break; 454 case hwmon_temp_emergency_hyst: 455 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST) 456 * 1000; 457 break; 458 default: 459 return -EOPNOTSUPP; 460 } 461 462 return 0; 463 } 464 465 static int 466 nouveau_fan_read(struct device *dev, u32 attr, int channel, long *val) 467 { 468 struct drm_device *drm_dev = dev_get_drvdata(dev); 469 struct nouveau_drm *drm = nouveau_drm(drm_dev); 470 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 471 472 if (!therm) 473 return -EOPNOTSUPP; 474 475 switch (attr) { 476 case hwmon_fan_input: 477 *val = nvkm_therm_fan_sense(therm); 478 break; 479 default: 480 return -EOPNOTSUPP; 481 } 482 483 return 0; 484 } 485 486 static int 487 nouveau_in_read(struct device *dev, u32 attr, int channel, long *val) 488 { 489 struct drm_device *drm_dev = dev_get_drvdata(dev); 490 struct nouveau_drm *drm = nouveau_drm(drm_dev); 491 struct nvkm_volt *volt = nvxx_volt(&drm->client.device); 492 int ret; 493 494 if (!volt) 495 return -EOPNOTSUPP; 496 497 switch (attr) { 498 case hwmon_in_input: 499 ret = nvkm_volt_get(volt); 500 *val = ret < 0 ? ret : (ret / 1000); 501 break; 502 case hwmon_in_min: 503 *val = volt->min_uv > 0 ? (volt->min_uv / 1000) : -ENODEV; 504 break; 505 case hwmon_in_max: 506 *val = volt->max_uv > 0 ? (volt->max_uv / 1000) : -ENODEV; 507 break; 508 default: 509 return -EOPNOTSUPP; 510 } 511 512 return 0; 513 } 514 515 static int 516 nouveau_pwm_read(struct device *dev, u32 attr, int channel, long *val) 517 { 518 struct drm_device *drm_dev = dev_get_drvdata(dev); 519 struct nouveau_drm *drm = nouveau_drm(drm_dev); 520 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 521 522 if (!therm || !therm->attr_get || !therm->fan_get) 523 return -EOPNOTSUPP; 524 525 switch (attr) { 526 case hwmon_pwm_enable: 527 *val = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE); 528 break; 529 case hwmon_pwm_input: 530 *val = therm->fan_get(therm); 531 break; 532 default: 533 return -EOPNOTSUPP; 534 } 535 536 return 0; 537 } 538 539 static int 540 nouveau_power_read(struct device *dev, u32 attr, int channel, long *val) 541 { 542 struct drm_device *drm_dev = dev_get_drvdata(dev); 543 struct nouveau_drm *drm = nouveau_drm(drm_dev); 544 struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device); 545 546 if (!iccsense) 547 return -EOPNOTSUPP; 548 549 switch (attr) { 550 case hwmon_power_input: 551 *val = nvkm_iccsense_read_all(iccsense); 552 break; 553 case hwmon_power_max: 554 *val = iccsense->power_w_max; 555 break; 556 case hwmon_power_crit: 557 *val = iccsense->power_w_crit; 558 break; 559 default: 560 return -EOPNOTSUPP; 561 } 562 563 return 0; 564 } 565 566 static int 567 nouveau_temp_write(struct device *dev, u32 attr, int channel, long val) 568 { 569 struct drm_device *drm_dev = dev_get_drvdata(dev); 570 struct nouveau_drm *drm = nouveau_drm(drm_dev); 571 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 572 573 if (!therm || !therm->attr_set) 574 return -EOPNOTSUPP; 575 576 switch (attr) { 577 case hwmon_temp_max: 578 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, 579 val / 1000); 580 case hwmon_temp_max_hyst: 581 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST, 582 val / 1000); 583 case hwmon_temp_crit: 584 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL, 585 val / 1000); 586 case hwmon_temp_crit_hyst: 587 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST, 588 val / 1000); 589 case hwmon_temp_emergency: 590 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN, 591 val / 1000); 592 case hwmon_temp_emergency_hyst: 593 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST, 594 val / 1000); 595 default: 596 return -EOPNOTSUPP; 597 } 598 } 599 600 static int 601 nouveau_pwm_write(struct device *dev, u32 attr, int channel, long val) 602 { 603 struct drm_device *drm_dev = dev_get_drvdata(dev); 604 struct nouveau_drm *drm = nouveau_drm(drm_dev); 605 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 606 607 if (!therm || !therm->attr_set) 608 return -EOPNOTSUPP; 609 610 switch (attr) { 611 case hwmon_pwm_input: 612 return therm->fan_set(therm, val); 613 case hwmon_pwm_enable: 614 return therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, val); 615 default: 616 return -EOPNOTSUPP; 617 } 618 } 619 620 static umode_t 621 nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, 622 int channel) 623 { 624 switch (type) { 625 case hwmon_chip: 626 return nouveau_chip_is_visible(data, attr, channel); 627 case hwmon_temp: 628 return nouveau_temp_is_visible(data, attr, channel); 629 case hwmon_fan: 630 return nouveau_fan_is_visible(data, attr, channel); 631 case hwmon_in: 632 return nouveau_input_is_visible(data, attr, channel); 633 case hwmon_pwm: 634 return nouveau_pwm_is_visible(data, attr, channel); 635 case hwmon_power: 636 return nouveau_power_is_visible(data, attr, channel); 637 default: 638 return 0; 639 } 640 } 641 642 static const char input_label[] = "GPU core"; 643 644 static int 645 nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr, 646 int channel, const char **buf) 647 { 648 if (type == hwmon_in && attr == hwmon_in_label) { 649 *buf = input_label; 650 return 0; 651 } 652 653 return -EOPNOTSUPP; 654 } 655 656 static int 657 nouveau_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, 658 int channel, long *val) 659 { 660 switch (type) { 661 case hwmon_chip: 662 return nouveau_chip_read(dev, attr, channel, val); 663 case hwmon_temp: 664 return nouveau_temp_read(dev, attr, channel, val); 665 case hwmon_fan: 666 return nouveau_fan_read(dev, attr, channel, val); 667 case hwmon_in: 668 return nouveau_in_read(dev, attr, channel, val); 669 case hwmon_pwm: 670 return nouveau_pwm_read(dev, attr, channel, val); 671 case hwmon_power: 672 return nouveau_power_read(dev, attr, channel, val); 673 default: 674 return -EOPNOTSUPP; 675 } 676 } 677 678 static int 679 nouveau_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, 680 int channel, long val) 681 { 682 switch (type) { 683 case hwmon_temp: 684 return nouveau_temp_write(dev, attr, channel, val); 685 case hwmon_pwm: 686 return nouveau_pwm_write(dev, attr, channel, val); 687 default: 688 return -EOPNOTSUPP; 689 } 690 } 691 692 static const struct hwmon_ops nouveau_hwmon_ops = { 693 .is_visible = nouveau_is_visible, 694 .read = nouveau_read, 695 .read_string = nouveau_read_string, 696 .write = nouveau_write, 697 }; 698 699 static const struct hwmon_chip_info nouveau_chip_info = { 700 .ops = &nouveau_hwmon_ops, 701 .info = nouveau_info, 702 }; 703 #endif 704 705 int 706 nouveau_hwmon_init(struct drm_device *dev) 707 { 708 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 709 struct nouveau_drm *drm = nouveau_drm(dev); 710 struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device); 711 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 712 struct nvkm_volt *volt = nvxx_volt(&drm->client.device); 713 const struct attribute_group *special_groups[N_ATTR_GROUPS]; 714 struct nouveau_hwmon *hwmon; 715 struct device *hwmon_dev; 716 int ret = 0; 717 int i = 0; 718 719 if (!iccsense && !therm && !volt) { 720 NV_DEBUG(drm, "Skipping hwmon registration\n"); 721 return 0; 722 } 723 724 hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); 725 if (!hwmon) 726 return -ENOMEM; 727 hwmon->dev = dev; 728 729 if (therm && therm->attr_get && therm->attr_set) { 730 if (nvkm_therm_temp_get(therm) >= 0) 731 special_groups[i++] = &temp1_auto_point_sensor_group; 732 if (therm->fan_get && therm->fan_get(therm) >= 0) 733 special_groups[i++] = &pwm_fan_sensor_group; 734 } 735 736 special_groups[i] = 0; 737 hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev, 738 &nouveau_chip_info, 739 special_groups); 740 if (IS_ERR(hwmon_dev)) { 741 ret = PTR_ERR(hwmon_dev); 742 NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret); 743 return ret; 744 } 745 746 hwmon->hwmon = hwmon_dev; 747 return 0; 748 #else 749 return 0; 750 #endif 751 } 752 753 void 754 nouveau_hwmon_fini(struct drm_device *dev) 755 { 756 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 757 struct nouveau_hwmon *hwmon = nouveau_hwmon(dev); 758 759 if (!hwmon) 760 return; 761 762 if (hwmon->hwmon) 763 hwmon_device_unregister(hwmon->hwmon); 764 765 nouveau_drm(dev)->hwmon = NULL; 766 kfree(hwmon); 767 #endif 768 } 769