2 * Copyright 2010 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include <linux/acpi.h>
28 #include <linux/power_supply.h>
29 #include <linux/hwmon.h>
30 #include <linux/hwmon-sysfs.h>
34 #include "nouveau_drm.h"
35 #include "nouveau_hwmon.h"
37 #include <nvkm/subdev/volt.h>
39 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
41 nouveau_hwmon_show_temp(struct device
*d
, struct device_attribute
*a
, char *buf
)
43 struct drm_device
*dev
= dev_get_drvdata(d
);
44 struct nouveau_drm
*drm
= nouveau_drm(dev
);
45 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
46 int temp
= nvkm_therm_temp_get(therm
);
51 return snprintf(buf
, PAGE_SIZE
, "%d\n", temp
* 1000);
53 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
, nouveau_hwmon_show_temp
,
57 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device
*d
,
58 struct device_attribute
*a
, char *buf
)
60 return snprintf(buf
, PAGE_SIZE
, "%d\n", 100);
62 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm
, S_IRUGO
,
63 nouveau_hwmon_show_temp1_auto_point1_pwm
, NULL
, 0);
66 nouveau_hwmon_temp1_auto_point1_temp(struct device
*d
,
67 struct device_attribute
*a
, char *buf
)
69 struct drm_device
*dev
= dev_get_drvdata(d
);
70 struct nouveau_drm
*drm
= nouveau_drm(dev
);
71 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
73 return snprintf(buf
, PAGE_SIZE
, "%d\n",
74 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST
) * 1000);
77 nouveau_hwmon_set_temp1_auto_point1_temp(struct device
*d
,
78 struct device_attribute
*a
,
79 const char *buf
, size_t count
)
81 struct drm_device
*dev
= dev_get_drvdata(d
);
82 struct nouveau_drm
*drm
= nouveau_drm(dev
);
83 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
86 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
89 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST
,
94 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp
, S_IRUGO
| S_IWUSR
,
95 nouveau_hwmon_temp1_auto_point1_temp
,
96 nouveau_hwmon_set_temp1_auto_point1_temp
, 0);
99 nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device
*d
,
100 struct device_attribute
*a
, char *buf
)
102 struct drm_device
*dev
= dev_get_drvdata(d
);
103 struct nouveau_drm
*drm
= nouveau_drm(dev
);
104 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
106 return snprintf(buf
, PAGE_SIZE
, "%d\n",
107 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST
) * 1000);
110 nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device
*d
,
111 struct device_attribute
*a
,
112 const char *buf
, size_t count
)
114 struct drm_device
*dev
= dev_get_drvdata(d
);
115 struct nouveau_drm
*drm
= nouveau_drm(dev
);
116 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
119 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
122 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST
,
127 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst
, S_IRUGO
| S_IWUSR
,
128 nouveau_hwmon_temp1_auto_point1_temp_hyst
,
129 nouveau_hwmon_set_temp1_auto_point1_temp_hyst
, 0);
132 nouveau_hwmon_max_temp(struct device
*d
, struct device_attribute
*a
, char *buf
)
134 struct drm_device
*dev
= dev_get_drvdata(d
);
135 struct nouveau_drm
*drm
= nouveau_drm(dev
);
136 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
138 return snprintf(buf
, PAGE_SIZE
, "%d\n",
139 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK
) * 1000);
142 nouveau_hwmon_set_max_temp(struct device
*d
, struct device_attribute
*a
,
143 const char *buf
, size_t count
)
145 struct drm_device
*dev
= dev_get_drvdata(d
);
146 struct nouveau_drm
*drm
= nouveau_drm(dev
);
147 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
150 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
153 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK
, value
/ 1000);
157 static SENSOR_DEVICE_ATTR(temp1_max
, S_IRUGO
| S_IWUSR
, nouveau_hwmon_max_temp
,
158 nouveau_hwmon_set_max_temp
,
162 nouveau_hwmon_max_temp_hyst(struct device
*d
, struct device_attribute
*a
,
165 struct drm_device
*dev
= dev_get_drvdata(d
);
166 struct nouveau_drm
*drm
= nouveau_drm(dev
);
167 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
169 return snprintf(buf
, PAGE_SIZE
, "%d\n",
170 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST
) * 1000);
173 nouveau_hwmon_set_max_temp_hyst(struct device
*d
, struct device_attribute
*a
,
174 const char *buf
, size_t count
)
176 struct drm_device
*dev
= dev_get_drvdata(d
);
177 struct nouveau_drm
*drm
= nouveau_drm(dev
);
178 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
181 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
184 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST
,
189 static SENSOR_DEVICE_ATTR(temp1_max_hyst
, S_IRUGO
| S_IWUSR
,
190 nouveau_hwmon_max_temp_hyst
,
191 nouveau_hwmon_set_max_temp_hyst
, 0);
194 nouveau_hwmon_critical_temp(struct device
*d
, struct device_attribute
*a
,
197 struct drm_device
*dev
= dev_get_drvdata(d
);
198 struct nouveau_drm
*drm
= nouveau_drm(dev
);
199 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
201 return snprintf(buf
, PAGE_SIZE
, "%d\n",
202 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_CRITICAL
) * 1000);
205 nouveau_hwmon_set_critical_temp(struct device
*d
, struct device_attribute
*a
,
209 struct drm_device
*dev
= dev_get_drvdata(d
);
210 struct nouveau_drm
*drm
= nouveau_drm(dev
);
211 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
214 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
217 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_CRITICAL
, value
/ 1000);
221 static SENSOR_DEVICE_ATTR(temp1_crit
, S_IRUGO
| S_IWUSR
,
222 nouveau_hwmon_critical_temp
,
223 nouveau_hwmon_set_critical_temp
,
227 nouveau_hwmon_critical_temp_hyst(struct device
*d
, struct device_attribute
*a
,
230 struct drm_device
*dev
= dev_get_drvdata(d
);
231 struct nouveau_drm
*drm
= nouveau_drm(dev
);
232 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
234 return snprintf(buf
, PAGE_SIZE
, "%d\n",
235 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_CRITICAL_HYST
) * 1000);
238 nouveau_hwmon_set_critical_temp_hyst(struct device
*d
,
239 struct device_attribute
*a
,
243 struct drm_device
*dev
= dev_get_drvdata(d
);
244 struct nouveau_drm
*drm
= nouveau_drm(dev
);
245 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
248 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
251 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_CRITICAL_HYST
,
256 static SENSOR_DEVICE_ATTR(temp1_crit_hyst
, S_IRUGO
| S_IWUSR
,
257 nouveau_hwmon_critical_temp_hyst
,
258 nouveau_hwmon_set_critical_temp_hyst
, 0);
260 nouveau_hwmon_emergency_temp(struct device
*d
, struct device_attribute
*a
,
263 struct drm_device
*dev
= dev_get_drvdata(d
);
264 struct nouveau_drm
*drm
= nouveau_drm(dev
);
265 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
267 return snprintf(buf
, PAGE_SIZE
, "%d\n",
268 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN
) * 1000);
271 nouveau_hwmon_set_emergency_temp(struct device
*d
, struct device_attribute
*a
,
275 struct drm_device
*dev
= dev_get_drvdata(d
);
276 struct nouveau_drm
*drm
= nouveau_drm(dev
);
277 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
280 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
283 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN
, value
/ 1000);
287 static SENSOR_DEVICE_ATTR(temp1_emergency
, S_IRUGO
| S_IWUSR
,
288 nouveau_hwmon_emergency_temp
,
289 nouveau_hwmon_set_emergency_temp
,
293 nouveau_hwmon_emergency_temp_hyst(struct device
*d
, struct device_attribute
*a
,
296 struct drm_device
*dev
= dev_get_drvdata(d
);
297 struct nouveau_drm
*drm
= nouveau_drm(dev
);
298 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
300 return snprintf(buf
, PAGE_SIZE
, "%d\n",
301 therm
->attr_get(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST
) * 1000);
304 nouveau_hwmon_set_emergency_temp_hyst(struct device
*d
,
305 struct device_attribute
*a
,
309 struct drm_device
*dev
= dev_get_drvdata(d
);
310 struct nouveau_drm
*drm
= nouveau_drm(dev
);
311 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
314 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
317 therm
->attr_set(therm
, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST
,
322 static SENSOR_DEVICE_ATTR(temp1_emergency_hyst
, S_IRUGO
| S_IWUSR
,
323 nouveau_hwmon_emergency_temp_hyst
,
324 nouveau_hwmon_set_emergency_temp_hyst
,
327 static ssize_t
nouveau_hwmon_show_name(struct device
*dev
,
328 struct device_attribute
*attr
,
331 return sprintf(buf
, "nouveau\n");
333 static SENSOR_DEVICE_ATTR(name
, S_IRUGO
, nouveau_hwmon_show_name
, NULL
, 0);
335 static ssize_t
nouveau_hwmon_show_update_rate(struct device
*dev
,
336 struct device_attribute
*attr
,
339 return sprintf(buf
, "1000\n");
341 static SENSOR_DEVICE_ATTR(update_rate
, S_IRUGO
,
342 nouveau_hwmon_show_update_rate
,
346 nouveau_hwmon_show_fan1_input(struct device
*d
, struct device_attribute
*attr
,
349 struct drm_device
*dev
= dev_get_drvdata(d
);
350 struct nouveau_drm
*drm
= nouveau_drm(dev
);
351 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
353 return snprintf(buf
, PAGE_SIZE
, "%d\n", nvkm_therm_fan_sense(therm
));
355 static SENSOR_DEVICE_ATTR(fan1_input
, S_IRUGO
, nouveau_hwmon_show_fan1_input
,
359 nouveau_hwmon_get_pwm1_enable(struct device
*d
,
360 struct device_attribute
*a
, char *buf
)
362 struct drm_device
*dev
= dev_get_drvdata(d
);
363 struct nouveau_drm
*drm
= nouveau_drm(dev
);
364 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
367 ret
= therm
->attr_get(therm
, NVKM_THERM_ATTR_FAN_MODE
);
371 return sprintf(buf
, "%i\n", ret
);
375 nouveau_hwmon_set_pwm1_enable(struct device
*d
, struct device_attribute
*a
,
376 const char *buf
, size_t count
)
378 struct drm_device
*dev
= dev_get_drvdata(d
);
379 struct nouveau_drm
*drm
= nouveau_drm(dev
);
380 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
384 ret
= kstrtol(buf
, 10, &value
);
388 ret
= therm
->attr_set(therm
, NVKM_THERM_ATTR_FAN_MODE
, value
);
394 static SENSOR_DEVICE_ATTR(pwm1_enable
, S_IRUGO
| S_IWUSR
,
395 nouveau_hwmon_get_pwm1_enable
,
396 nouveau_hwmon_set_pwm1_enable
, 0);
399 nouveau_hwmon_get_pwm1(struct device
*d
, struct device_attribute
*a
, char *buf
)
401 struct drm_device
*dev
= dev_get_drvdata(d
);
402 struct nouveau_drm
*drm
= nouveau_drm(dev
);
403 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
406 ret
= therm
->fan_get(therm
);
410 return sprintf(buf
, "%i\n", ret
);
414 nouveau_hwmon_set_pwm1(struct device
*d
, struct device_attribute
*a
,
415 const char *buf
, size_t count
)
417 struct drm_device
*dev
= dev_get_drvdata(d
);
418 struct nouveau_drm
*drm
= nouveau_drm(dev
);
419 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
423 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
426 ret
= therm
->fan_set(therm
, value
);
433 static SENSOR_DEVICE_ATTR(pwm1
, S_IRUGO
| S_IWUSR
,
434 nouveau_hwmon_get_pwm1
,
435 nouveau_hwmon_set_pwm1
, 0);
438 nouveau_hwmon_get_pwm1_min(struct device
*d
,
439 struct device_attribute
*a
, char *buf
)
441 struct drm_device
*dev
= dev_get_drvdata(d
);
442 struct nouveau_drm
*drm
= nouveau_drm(dev
);
443 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
446 ret
= therm
->attr_get(therm
, NVKM_THERM_ATTR_FAN_MIN_DUTY
);
450 return sprintf(buf
, "%i\n", ret
);
454 nouveau_hwmon_set_pwm1_min(struct device
*d
, struct device_attribute
*a
,
455 const char *buf
, size_t count
)
457 struct drm_device
*dev
= dev_get_drvdata(d
);
458 struct nouveau_drm
*drm
= nouveau_drm(dev
);
459 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
463 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
466 ret
= therm
->attr_set(therm
, NVKM_THERM_ATTR_FAN_MIN_DUTY
, value
);
473 static SENSOR_DEVICE_ATTR(pwm1_min
, S_IRUGO
| S_IWUSR
,
474 nouveau_hwmon_get_pwm1_min
,
475 nouveau_hwmon_set_pwm1_min
, 0);
478 nouveau_hwmon_get_pwm1_max(struct device
*d
,
479 struct device_attribute
*a
, char *buf
)
481 struct drm_device
*dev
= dev_get_drvdata(d
);
482 struct nouveau_drm
*drm
= nouveau_drm(dev
);
483 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
486 ret
= therm
->attr_get(therm
, NVKM_THERM_ATTR_FAN_MAX_DUTY
);
490 return sprintf(buf
, "%i\n", ret
);
494 nouveau_hwmon_set_pwm1_max(struct device
*d
, struct device_attribute
*a
,
495 const char *buf
, size_t count
)
497 struct drm_device
*dev
= dev_get_drvdata(d
);
498 struct nouveau_drm
*drm
= nouveau_drm(dev
);
499 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
503 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
506 ret
= therm
->attr_set(therm
, NVKM_THERM_ATTR_FAN_MAX_DUTY
, value
);
513 static SENSOR_DEVICE_ATTR(pwm1_max
, S_IRUGO
| S_IWUSR
,
514 nouveau_hwmon_get_pwm1_max
,
515 nouveau_hwmon_set_pwm1_max
, 0);
518 nouveau_hwmon_get_in0_input(struct device
*d
,
519 struct device_attribute
*a
, char *buf
)
521 struct drm_device
*dev
= dev_get_drvdata(d
);
522 struct nouveau_drm
*drm
= nouveau_drm(dev
);
523 struct nvkm_volt
*volt
= nvxx_volt(&drm
->device
);
526 ret
= nvkm_volt_get(volt
);
530 return sprintf(buf
, "%i\n", ret
/ 1000);
533 static SENSOR_DEVICE_ATTR(in0_input
, S_IRUGO
,
534 nouveau_hwmon_get_in0_input
, NULL
, 0);
537 nouveau_hwmon_get_in0_label(struct device
*d
,
538 struct device_attribute
*a
, char *buf
)
540 return sprintf(buf
, "GPU core\n");
543 static SENSOR_DEVICE_ATTR(in0_label
, S_IRUGO
,
544 nouveau_hwmon_get_in0_label
, NULL
, 0);
546 static struct attribute
*hwmon_default_attributes
[] = {
547 &sensor_dev_attr_name
.dev_attr
.attr
,
548 &sensor_dev_attr_update_rate
.dev_attr
.attr
,
551 static struct attribute
*hwmon_temp_attributes
[] = {
552 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
553 &sensor_dev_attr_temp1_auto_point1_pwm
.dev_attr
.attr
,
554 &sensor_dev_attr_temp1_auto_point1_temp
.dev_attr
.attr
,
555 &sensor_dev_attr_temp1_auto_point1_temp_hyst
.dev_attr
.attr
,
556 &sensor_dev_attr_temp1_max
.dev_attr
.attr
,
557 &sensor_dev_attr_temp1_max_hyst
.dev_attr
.attr
,
558 &sensor_dev_attr_temp1_crit
.dev_attr
.attr
,
559 &sensor_dev_attr_temp1_crit_hyst
.dev_attr
.attr
,
560 &sensor_dev_attr_temp1_emergency
.dev_attr
.attr
,
561 &sensor_dev_attr_temp1_emergency_hyst
.dev_attr
.attr
,
564 static struct attribute
*hwmon_fan_rpm_attributes
[] = {
565 &sensor_dev_attr_fan1_input
.dev_attr
.attr
,
568 static struct attribute
*hwmon_pwm_fan_attributes
[] = {
569 &sensor_dev_attr_pwm1_enable
.dev_attr
.attr
,
570 &sensor_dev_attr_pwm1
.dev_attr
.attr
,
571 &sensor_dev_attr_pwm1_min
.dev_attr
.attr
,
572 &sensor_dev_attr_pwm1_max
.dev_attr
.attr
,
576 static struct attribute
*hwmon_in0_attributes
[] = {
577 &sensor_dev_attr_in0_input
.dev_attr
.attr
,
578 &sensor_dev_attr_in0_label
.dev_attr
.attr
,
582 static const struct attribute_group hwmon_default_attrgroup
= {
583 .attrs
= hwmon_default_attributes
,
585 static const struct attribute_group hwmon_temp_attrgroup
= {
586 .attrs
= hwmon_temp_attributes
,
588 static const struct attribute_group hwmon_fan_rpm_attrgroup
= {
589 .attrs
= hwmon_fan_rpm_attributes
,
591 static const struct attribute_group hwmon_pwm_fan_attrgroup
= {
592 .attrs
= hwmon_pwm_fan_attributes
,
594 static const struct attribute_group hwmon_in0_attrgroup
= {
595 .attrs
= hwmon_in0_attributes
,
600 nouveau_hwmon_init(struct drm_device
*dev
)
602 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
603 struct nouveau_drm
*drm
= nouveau_drm(dev
);
604 struct nvkm_therm
*therm
= nvxx_therm(&drm
->device
);
605 struct nvkm_volt
*volt
= nvxx_volt(&drm
->device
);
606 struct nouveau_hwmon
*hwmon
;
607 struct device
*hwmon_dev
;
610 hwmon
= drm
->hwmon
= kzalloc(sizeof(*hwmon
), GFP_KERNEL
);
615 if (!therm
|| !therm
->attr_get
|| !therm
->attr_set
)
618 hwmon_dev
= hwmon_device_register(&dev
->pdev
->dev
);
619 if (IS_ERR(hwmon_dev
)) {
620 ret
= PTR_ERR(hwmon_dev
);
621 NV_ERROR(drm
, "Unable to register hwmon device: %d\n", ret
);
624 dev_set_drvdata(hwmon_dev
, dev
);
626 /* set the default attributes */
627 ret
= sysfs_create_group(&hwmon_dev
->kobj
, &hwmon_default_attrgroup
);
631 /* if the card has a working thermal sensor */
632 if (nvkm_therm_temp_get(therm
) >= 0) {
633 ret
= sysfs_create_group(&hwmon_dev
->kobj
, &hwmon_temp_attrgroup
);
638 /* if the card has a pwm fan */
639 /*XXX: incorrect, need better detection for this, some boards have
640 * the gpio entries for pwm fan control even when there's no
641 * actual fan connected to it... therm table? */
642 if (therm
->fan_get
&& therm
->fan_get(therm
) >= 0) {
643 ret
= sysfs_create_group(&hwmon_dev
->kobj
,
644 &hwmon_pwm_fan_attrgroup
);
649 /* if the card can read the fan rpm */
650 if (nvkm_therm_fan_sense(therm
) >= 0) {
651 ret
= sysfs_create_group(&hwmon_dev
->kobj
,
652 &hwmon_fan_rpm_attrgroup
);
657 if (volt
&& nvkm_volt_get(volt
) >= 0) {
658 ret
= sysfs_create_group(&hwmon_dev
->kobj
,
659 &hwmon_in0_attrgroup
);
665 hwmon
->hwmon
= hwmon_dev
;
670 NV_ERROR(drm
, "Unable to create some hwmon sysfs files: %d\n", ret
);
671 hwmon_device_unregister(hwmon_dev
);
680 nouveau_hwmon_fini(struct drm_device
*dev
)
682 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
683 struct nouveau_hwmon
*hwmon
= nouveau_hwmon(dev
);
686 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_default_attrgroup
);
687 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_temp_attrgroup
);
688 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_pwm_fan_attrgroup
);
689 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_fan_rpm_attrgroup
);
690 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_in0_attrgroup
);
692 hwmon_device_unregister(hwmon
->hwmon
);
695 nouveau_drm(dev
)->hwmon
= NULL
;