root/drivers/gpu/drm/nouveau/nouveau_hwmon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nouveau_hwmon_show_temp1_auto_point1_pwm
  2. nouveau_hwmon_temp1_auto_point1_temp
  3. nouveau_hwmon_set_temp1_auto_point1_temp
  4. nouveau_hwmon_temp1_auto_point1_temp_hyst
  5. nouveau_hwmon_set_temp1_auto_point1_temp_hyst
  6. nouveau_hwmon_get_pwm1_max
  7. nouveau_hwmon_get_pwm1_min
  8. nouveau_hwmon_set_pwm1_min
  9. nouveau_hwmon_set_pwm1_max
  10. nouveau_chip_is_visible
  11. nouveau_power_is_visible
  12. nouveau_temp_is_visible
  13. nouveau_pwm_is_visible
  14. nouveau_input_is_visible
  15. nouveau_fan_is_visible
  16. nouveau_chip_read
  17. nouveau_temp_read
  18. nouveau_fan_read
  19. nouveau_in_read
  20. nouveau_pwm_read
  21. nouveau_power_read
  22. nouveau_temp_write
  23. nouveau_pwm_write
  24. nouveau_is_visible
  25. nouveau_read_string
  26. nouveau_read
  27. nouveau_write
  28. nouveau_hwmon_init
  29. nouveau_hwmon_fini

   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 
  40 static ssize_t
  41 nouveau_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 }
  46 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  47                           nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
  48 
  49 static ssize_t
  50 nouveau_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 }
  60 static ssize_t
  61 nouveau_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 }
  78 static 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 
  82 static ssize_t
  83 nouveau_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 }
  93 static ssize_t
  94 nouveau_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 }
 111 static 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 
 115 static ssize_t
 116 nouveau_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 
 131 static ssize_t
 132 nouveau_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 
 147 static ssize_t
 148 nouveau_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 }
 166 static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
 167                           nouveau_hwmon_get_pwm1_min,
 168                           nouveau_hwmon_set_pwm1_min, 0);
 169 
 170 static ssize_t
 171 nouveau_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 }
 189 static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
 190                           nouveau_hwmon_get_pwm1_max,
 191                           nouveau_hwmon_set_pwm1_max, 0);
 192 
 193 static 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 };
 198 static const struct attribute_group pwm_fan_sensor_group = {
 199         .attrs = pwm_fan_sensor_attrs,
 200 };
 201 
 202 static 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 };
 208 static 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 
 214 static const u32 nouveau_config_chip[] = {
 215         HWMON_C_UPDATE_INTERVAL,
 216         0
 217 };
 218 
 219 static const u32 nouveau_config_in[] = {
 220         HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
 221         0
 222 };
 223 
 224 static 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 
 231 static const u32 nouveau_config_fan[] = {
 232         HWMON_F_INPUT,
 233         0
 234 };
 235 
 236 static const u32 nouveau_config_pwm[] = {
 237         HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
 238         0
 239 };
 240 
 241 static const u32 nouveau_config_power[] = {
 242         HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
 243         0
 244 };
 245 
 246 static const struct hwmon_channel_info nouveau_chip = {
 247         .type = hwmon_chip,
 248         .config = nouveau_config_chip,
 249 };
 250 
 251 static const struct hwmon_channel_info nouveau_temp = {
 252         .type = hwmon_temp,
 253         .config = nouveau_config_temp,
 254 };
 255 
 256 static const struct hwmon_channel_info nouveau_fan = {
 257         .type = hwmon_fan,
 258         .config = nouveau_config_fan,
 259 };
 260 
 261 static const struct hwmon_channel_info nouveau_in = {
 262         .type = hwmon_in,
 263         .config = nouveau_config_in,
 264 };
 265 
 266 static const struct hwmon_channel_info nouveau_pwm = {
 267         .type = hwmon_pwm,
 268         .config = nouveau_config_pwm,
 269 };
 270 
 271 static const struct hwmon_channel_info nouveau_power = {
 272         .type = hwmon_power,
 273         .config = nouveau_config_power,
 274 };
 275 
 276 static 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 
 286 static umode_t
 287 nouveau_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 
 297 static umode_t
 298 nouveau_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 
 322 static umode_t
 323 nouveau_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 
 346 static umode_t
 347 nouveau_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 
 365 static umode_t
 366 nouveau_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 
 385 static umode_t
 386 nouveau_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 
 402 static int
 403 nouveau_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 
 416 static int
 417 nouveau_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 
 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                 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 
 488 static int
 489 nouveau_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 
 519 static int
 520 nouveau_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 
 545 static int
 546 nouveau_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 
 574 static int
 575 nouveau_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 
 608 static int
 609 nouveau_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 
 628 static umode_t
 629 nouveau_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 
 650 static const char input_label[] = "GPU core";
 651 
 652 static int
 653 nouveau_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 
 664 static int
 665 nouveau_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 
 686 static int
 687 nouveau_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 
 700 static 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 
 707 static const struct hwmon_chip_info nouveau_chip_info = {
 708         .ops = &nouveau_hwmon_ops,
 709         .info = nouveau_info,
 710 };
 711 #endif
 712 
 713 int
 714 nouveau_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] = 0;
 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 
 761 void
 762 nouveau_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 }

/* [<][>][^][v][top][bottom][index][help] */