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 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON) 432 return -EINVAL; 433 ret = nvkm_therm_temp_get(therm); 434 *val = ret < 0 ? ret : (ret * 1000); 435 break; 436 case hwmon_temp_max: 437 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) 438 * 1000; 439 break; 440 case hwmon_temp_max_hyst: 441 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) 442 * 1000; 443 break; 444 case hwmon_temp_crit: 445 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) 446 * 1000; 447 break; 448 case hwmon_temp_crit_hyst: 449 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST) 450 * 1000; 451 break; 452 case hwmon_temp_emergency: 453 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN) 454 * 1000; 455 break; 456 case hwmon_temp_emergency_hyst: 457 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST) 458 * 1000; 459 break; 460 default: 461 return -EOPNOTSUPP; 462 } 463 464 return 0; 465 } 466 467 static int 468 nouveau_fan_read(struct device *dev, u32 attr, int channel, long *val) 469 { 470 struct drm_device *drm_dev = dev_get_drvdata(dev); 471 struct nouveau_drm *drm = nouveau_drm(drm_dev); 472 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 473 474 if (!therm) 475 return -EOPNOTSUPP; 476 477 switch (attr) { 478 case hwmon_fan_input: 479 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON) 480 return -EINVAL; 481 *val = nvkm_therm_fan_sense(therm); 482 break; 483 default: 484 return -EOPNOTSUPP; 485 } 486 487 return 0; 488 } 489 490 static int 491 nouveau_in_read(struct device *dev, u32 attr, int channel, long *val) 492 { 493 struct drm_device *drm_dev = dev_get_drvdata(dev); 494 struct nouveau_drm *drm = nouveau_drm(drm_dev); 495 struct nvkm_volt *volt = nvxx_volt(&drm->client.device); 496 int ret; 497 498 if (!volt) 499 return -EOPNOTSUPP; 500 501 switch (attr) { 502 case hwmon_in_input: 503 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON) 504 return -EINVAL; 505 ret = nvkm_volt_get(volt); 506 *val = ret < 0 ? ret : (ret / 1000); 507 break; 508 case hwmon_in_min: 509 *val = volt->min_uv > 0 ? (volt->min_uv / 1000) : -ENODEV; 510 break; 511 case hwmon_in_max: 512 *val = volt->max_uv > 0 ? (volt->max_uv / 1000) : -ENODEV; 513 break; 514 default: 515 return -EOPNOTSUPP; 516 } 517 518 return 0; 519 } 520 521 static int 522 nouveau_pwm_read(struct device *dev, u32 attr, int channel, long *val) 523 { 524 struct drm_device *drm_dev = dev_get_drvdata(dev); 525 struct nouveau_drm *drm = nouveau_drm(drm_dev); 526 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 527 528 if (!therm || !therm->attr_get || !therm->fan_get) 529 return -EOPNOTSUPP; 530 531 switch (attr) { 532 case hwmon_pwm_enable: 533 *val = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE); 534 break; 535 case hwmon_pwm_input: 536 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON) 537 return -EINVAL; 538 *val = therm->fan_get(therm); 539 break; 540 default: 541 return -EOPNOTSUPP; 542 } 543 544 return 0; 545 } 546 547 static int 548 nouveau_power_read(struct device *dev, u32 attr, int channel, long *val) 549 { 550 struct drm_device *drm_dev = dev_get_drvdata(dev); 551 struct nouveau_drm *drm = nouveau_drm(drm_dev); 552 struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device); 553 554 if (!iccsense) 555 return -EOPNOTSUPP; 556 557 switch (attr) { 558 case hwmon_power_input: 559 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON) 560 return -EINVAL; 561 *val = nvkm_iccsense_read_all(iccsense); 562 break; 563 case hwmon_power_max: 564 *val = iccsense->power_w_max; 565 break; 566 case hwmon_power_crit: 567 *val = iccsense->power_w_crit; 568 break; 569 default: 570 return -EOPNOTSUPP; 571 } 572 573 return 0; 574 } 575 576 static int 577 nouveau_temp_write(struct device *dev, u32 attr, int channel, long val) 578 { 579 struct drm_device *drm_dev = dev_get_drvdata(dev); 580 struct nouveau_drm *drm = nouveau_drm(drm_dev); 581 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 582 583 if (!therm || !therm->attr_set) 584 return -EOPNOTSUPP; 585 586 switch (attr) { 587 case hwmon_temp_max: 588 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, 589 val / 1000); 590 case hwmon_temp_max_hyst: 591 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST, 592 val / 1000); 593 case hwmon_temp_crit: 594 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL, 595 val / 1000); 596 case hwmon_temp_crit_hyst: 597 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST, 598 val / 1000); 599 case hwmon_temp_emergency: 600 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN, 601 val / 1000); 602 case hwmon_temp_emergency_hyst: 603 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST, 604 val / 1000); 605 default: 606 return -EOPNOTSUPP; 607 } 608 } 609 610 static int 611 nouveau_pwm_write(struct device *dev, u32 attr, int channel, long val) 612 { 613 struct drm_device *drm_dev = dev_get_drvdata(dev); 614 struct nouveau_drm *drm = nouveau_drm(drm_dev); 615 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 616 617 if (!therm || !therm->attr_set) 618 return -EOPNOTSUPP; 619 620 switch (attr) { 621 case hwmon_pwm_input: 622 return therm->fan_set(therm, val); 623 case hwmon_pwm_enable: 624 return therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, val); 625 default: 626 return -EOPNOTSUPP; 627 } 628 } 629 630 static umode_t 631 nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, 632 int channel) 633 { 634 switch (type) { 635 case hwmon_chip: 636 return nouveau_chip_is_visible(data, attr, channel); 637 case hwmon_temp: 638 return nouveau_temp_is_visible(data, attr, channel); 639 case hwmon_fan: 640 return nouveau_fan_is_visible(data, attr, channel); 641 case hwmon_in: 642 return nouveau_input_is_visible(data, attr, channel); 643 case hwmon_pwm: 644 return nouveau_pwm_is_visible(data, attr, channel); 645 case hwmon_power: 646 return nouveau_power_is_visible(data, attr, channel); 647 default: 648 return 0; 649 } 650 } 651 652 static const char input_label[] = "GPU core"; 653 654 static int 655 nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr, 656 int channel, const char **buf) 657 { 658 if (type == hwmon_in && attr == hwmon_in_label) { 659 *buf = input_label; 660 return 0; 661 } 662 663 return -EOPNOTSUPP; 664 } 665 666 static int 667 nouveau_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, 668 int channel, long *val) 669 { 670 switch (type) { 671 case hwmon_chip: 672 return nouveau_chip_read(dev, attr, channel, val); 673 case hwmon_temp: 674 return nouveau_temp_read(dev, attr, channel, val); 675 case hwmon_fan: 676 return nouveau_fan_read(dev, attr, channel, val); 677 case hwmon_in: 678 return nouveau_in_read(dev, attr, channel, val); 679 case hwmon_pwm: 680 return nouveau_pwm_read(dev, attr, channel, val); 681 case hwmon_power: 682 return nouveau_power_read(dev, attr, channel, val); 683 default: 684 return -EOPNOTSUPP; 685 } 686 } 687 688 static int 689 nouveau_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, 690 int channel, long val) 691 { 692 switch (type) { 693 case hwmon_temp: 694 return nouveau_temp_write(dev, attr, channel, val); 695 case hwmon_pwm: 696 return nouveau_pwm_write(dev, attr, channel, val); 697 default: 698 return -EOPNOTSUPP; 699 } 700 } 701 702 static const struct hwmon_ops nouveau_hwmon_ops = { 703 .is_visible = nouveau_is_visible, 704 .read = nouveau_read, 705 .read_string = nouveau_read_string, 706 .write = nouveau_write, 707 }; 708 709 static const struct hwmon_chip_info nouveau_chip_info = { 710 .ops = &nouveau_hwmon_ops, 711 .info = nouveau_info, 712 }; 713 #endif 714 715 int 716 nouveau_hwmon_init(struct drm_device *dev) 717 { 718 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 719 struct nouveau_drm *drm = nouveau_drm(dev); 720 struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device); 721 struct nvkm_therm *therm = nvxx_therm(&drm->client.device); 722 struct nvkm_volt *volt = nvxx_volt(&drm->client.device); 723 const struct attribute_group *special_groups[N_ATTR_GROUPS]; 724 struct nouveau_hwmon *hwmon; 725 struct device *hwmon_dev; 726 int ret = 0; 727 int i = 0; 728 729 if (!iccsense && !therm && !volt) { 730 NV_DEBUG(drm, "Skipping hwmon registration\n"); 731 return 0; 732 } 733 734 hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); 735 if (!hwmon) 736 return -ENOMEM; 737 hwmon->dev = dev; 738 739 if (therm && therm->attr_get && therm->attr_set) { 740 if (nvkm_therm_temp_get(therm) >= 0) 741 special_groups[i++] = &temp1_auto_point_sensor_group; 742 if (therm->fan_get && therm->fan_get(therm) >= 0) 743 special_groups[i++] = &pwm_fan_sensor_group; 744 } 745 746 special_groups[i] = 0; 747 hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev, 748 &nouveau_chip_info, 749 special_groups); 750 if (IS_ERR(hwmon_dev)) { 751 ret = PTR_ERR(hwmon_dev); 752 NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret); 753 return ret; 754 } 755 756 hwmon->hwmon = hwmon_dev; 757 return 0; 758 #else 759 return 0; 760 #endif 761 } 762 763 void 764 nouveau_hwmon_fini(struct drm_device *dev) 765 { 766 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 767 struct nouveau_hwmon *hwmon = nouveau_hwmon(dev); 768 769 if (!hwmon) 770 return; 771 772 if (hwmon->hwmon) 773 hwmon_device_unregister(hwmon->hwmon); 774 775 nouveau_drm(dev)->hwmon = NULL; 776 kfree(hwmon); 777 #endif 778 } 779