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