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 <subdev/gpio.h>
38 #include <subdev/timer.h>
39 #include <subdev/therm.h>
41 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
43 nouveau_hwmon_show_temp(struct device
*d
, struct device_attribute
*a
, char *buf
)
45 struct drm_device
*dev
= dev_get_drvdata(d
);
46 struct nouveau_drm
*drm
= nouveau_drm(dev
);
47 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
48 int temp
= therm
->temp_get(therm
);
53 return snprintf(buf
, PAGE_SIZE
, "%d\n", temp
* 1000);
55 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
, nouveau_hwmon_show_temp
,
59 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device
*d
,
60 struct device_attribute
*a
, char *buf
)
62 return snprintf(buf
, PAGE_SIZE
, "%d\n", 100);
64 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm
, S_IRUGO
,
65 nouveau_hwmon_show_temp1_auto_point1_pwm
, NULL
, 0);
68 nouveau_hwmon_temp1_auto_point1_temp(struct device
*d
,
69 struct device_attribute
*a
, char *buf
)
71 struct drm_device
*dev
= dev_get_drvdata(d
);
72 struct nouveau_drm
*drm
= nouveau_drm(dev
);
73 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
75 return snprintf(buf
, PAGE_SIZE
, "%d\n",
76 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST
) * 1000);
79 nouveau_hwmon_set_temp1_auto_point1_temp(struct device
*d
,
80 struct device_attribute
*a
,
81 const char *buf
, size_t count
)
83 struct drm_device
*dev
= dev_get_drvdata(d
);
84 struct nouveau_drm
*drm
= nouveau_drm(dev
);
85 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
88 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
91 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST
,
96 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp
, S_IRUGO
| S_IWUSR
,
97 nouveau_hwmon_temp1_auto_point1_temp
,
98 nouveau_hwmon_set_temp1_auto_point1_temp
, 0);
101 nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device
*d
,
102 struct device_attribute
*a
, char *buf
)
104 struct drm_device
*dev
= dev_get_drvdata(d
);
105 struct nouveau_drm
*drm
= nouveau_drm(dev
);
106 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
108 return snprintf(buf
, PAGE_SIZE
, "%d\n",
109 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST
) * 1000);
112 nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device
*d
,
113 struct device_attribute
*a
,
114 const char *buf
, size_t count
)
116 struct drm_device
*dev
= dev_get_drvdata(d
);
117 struct nouveau_drm
*drm
= nouveau_drm(dev
);
118 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
121 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
124 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST
,
129 static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst
, S_IRUGO
| S_IWUSR
,
130 nouveau_hwmon_temp1_auto_point1_temp_hyst
,
131 nouveau_hwmon_set_temp1_auto_point1_temp_hyst
, 0);
134 nouveau_hwmon_max_temp(struct device
*d
, struct device_attribute
*a
, char *buf
)
136 struct drm_device
*dev
= dev_get_drvdata(d
);
137 struct nouveau_drm
*drm
= nouveau_drm(dev
);
138 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
140 return snprintf(buf
, PAGE_SIZE
, "%d\n",
141 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK
) * 1000);
144 nouveau_hwmon_set_max_temp(struct device
*d
, struct device_attribute
*a
,
145 const char *buf
, size_t count
)
147 struct drm_device
*dev
= dev_get_drvdata(d
);
148 struct nouveau_drm
*drm
= nouveau_drm(dev
);
149 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
152 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
155 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK
, value
/ 1000);
159 static SENSOR_DEVICE_ATTR(temp1_max
, S_IRUGO
| S_IWUSR
, nouveau_hwmon_max_temp
,
160 nouveau_hwmon_set_max_temp
,
164 nouveau_hwmon_max_temp_hyst(struct device
*d
, struct device_attribute
*a
,
167 struct drm_device
*dev
= dev_get_drvdata(d
);
168 struct nouveau_drm
*drm
= nouveau_drm(dev
);
169 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
171 return snprintf(buf
, PAGE_SIZE
, "%d\n",
172 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST
) * 1000);
175 nouveau_hwmon_set_max_temp_hyst(struct device
*d
, struct device_attribute
*a
,
176 const char *buf
, size_t count
)
178 struct drm_device
*dev
= dev_get_drvdata(d
);
179 struct nouveau_drm
*drm
= nouveau_drm(dev
);
180 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
183 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
186 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST
,
191 static SENSOR_DEVICE_ATTR(temp1_max_hyst
, S_IRUGO
| S_IWUSR
,
192 nouveau_hwmon_max_temp_hyst
,
193 nouveau_hwmon_set_max_temp_hyst
, 0);
196 nouveau_hwmon_critical_temp(struct device
*d
, struct device_attribute
*a
,
199 struct drm_device
*dev
= dev_get_drvdata(d
);
200 struct nouveau_drm
*drm
= nouveau_drm(dev
);
201 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
203 return snprintf(buf
, PAGE_SIZE
, "%d\n",
204 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_CRITICAL
) * 1000);
207 nouveau_hwmon_set_critical_temp(struct device
*d
, struct device_attribute
*a
,
211 struct drm_device
*dev
= dev_get_drvdata(d
);
212 struct nouveau_drm
*drm
= nouveau_drm(dev
);
213 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
216 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
219 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_CRITICAL
, value
/ 1000);
223 static SENSOR_DEVICE_ATTR(temp1_crit
, S_IRUGO
| S_IWUSR
,
224 nouveau_hwmon_critical_temp
,
225 nouveau_hwmon_set_critical_temp
,
229 nouveau_hwmon_critical_temp_hyst(struct device
*d
, struct device_attribute
*a
,
232 struct drm_device
*dev
= dev_get_drvdata(d
);
233 struct nouveau_drm
*drm
= nouveau_drm(dev
);
234 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
236 return snprintf(buf
, PAGE_SIZE
, "%d\n",
237 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST
) * 1000);
240 nouveau_hwmon_set_critical_temp_hyst(struct device
*d
,
241 struct device_attribute
*a
,
245 struct drm_device
*dev
= dev_get_drvdata(d
);
246 struct nouveau_drm
*drm
= nouveau_drm(dev
);
247 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
250 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
253 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST
,
258 static SENSOR_DEVICE_ATTR(temp1_crit_hyst
, S_IRUGO
| S_IWUSR
,
259 nouveau_hwmon_critical_temp_hyst
,
260 nouveau_hwmon_set_critical_temp_hyst
, 0);
262 nouveau_hwmon_emergency_temp(struct device
*d
, struct device_attribute
*a
,
265 struct drm_device
*dev
= dev_get_drvdata(d
);
266 struct nouveau_drm
*drm
= nouveau_drm(dev
);
267 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
269 return snprintf(buf
, PAGE_SIZE
, "%d\n",
270 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN
) * 1000);
273 nouveau_hwmon_set_emergency_temp(struct device
*d
, struct device_attribute
*a
,
277 struct drm_device
*dev
= dev_get_drvdata(d
);
278 struct nouveau_drm
*drm
= nouveau_drm(dev
);
279 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
282 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
285 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN
, value
/ 1000);
289 static SENSOR_DEVICE_ATTR(temp1_emergency
, S_IRUGO
| S_IWUSR
,
290 nouveau_hwmon_emergency_temp
,
291 nouveau_hwmon_set_emergency_temp
,
295 nouveau_hwmon_emergency_temp_hyst(struct device
*d
, struct device_attribute
*a
,
298 struct drm_device
*dev
= dev_get_drvdata(d
);
299 struct nouveau_drm
*drm
= nouveau_drm(dev
);
300 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
302 return snprintf(buf
, PAGE_SIZE
, "%d\n",
303 therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST
) * 1000);
306 nouveau_hwmon_set_emergency_temp_hyst(struct device
*d
,
307 struct device_attribute
*a
,
311 struct drm_device
*dev
= dev_get_drvdata(d
);
312 struct nouveau_drm
*drm
= nouveau_drm(dev
);
313 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
316 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
319 therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST
,
324 static SENSOR_DEVICE_ATTR(temp1_emergency_hyst
, S_IRUGO
| S_IWUSR
,
325 nouveau_hwmon_emergency_temp_hyst
,
326 nouveau_hwmon_set_emergency_temp_hyst
,
329 static ssize_t
nouveau_hwmon_show_name(struct device
*dev
,
330 struct device_attribute
*attr
,
333 return sprintf(buf
, "nouveau\n");
335 static SENSOR_DEVICE_ATTR(name
, S_IRUGO
, nouveau_hwmon_show_name
, NULL
, 0);
337 static ssize_t
nouveau_hwmon_show_update_rate(struct device
*dev
,
338 struct device_attribute
*attr
,
341 return sprintf(buf
, "1000\n");
343 static SENSOR_DEVICE_ATTR(update_rate
, S_IRUGO
,
344 nouveau_hwmon_show_update_rate
,
348 nouveau_hwmon_show_fan1_input(struct device
*d
, struct device_attribute
*attr
,
351 struct drm_device
*dev
= dev_get_drvdata(d
);
352 struct nouveau_drm
*drm
= nouveau_drm(dev
);
353 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
355 return snprintf(buf
, PAGE_SIZE
, "%d\n", therm
->fan_sense(therm
));
357 static SENSOR_DEVICE_ATTR(fan1_input
, S_IRUGO
, nouveau_hwmon_show_fan1_input
,
361 nouveau_hwmon_get_pwm1_enable(struct device
*d
,
362 struct device_attribute
*a
, char *buf
)
364 struct drm_device
*dev
= dev_get_drvdata(d
);
365 struct nouveau_drm
*drm
= nouveau_drm(dev
);
366 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
369 ret
= therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_FAN_MODE
);
373 return sprintf(buf
, "%i\n", ret
);
377 nouveau_hwmon_set_pwm1_enable(struct device
*d
, struct device_attribute
*a
,
378 const char *buf
, size_t count
)
380 struct drm_device
*dev
= dev_get_drvdata(d
);
381 struct nouveau_drm
*drm
= nouveau_drm(dev
);
382 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
386 ret
= kstrtol(buf
, 10, &value
);
390 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MODE
, value
);
396 static SENSOR_DEVICE_ATTR(pwm1_enable
, S_IRUGO
| S_IWUSR
,
397 nouveau_hwmon_get_pwm1_enable
,
398 nouveau_hwmon_set_pwm1_enable
, 0);
401 nouveau_hwmon_get_pwm1(struct device
*d
, struct device_attribute
*a
, char *buf
)
403 struct drm_device
*dev
= dev_get_drvdata(d
);
404 struct nouveau_drm
*drm
= nouveau_drm(dev
);
405 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
408 ret
= therm
->fan_get(therm
);
412 return sprintf(buf
, "%i\n", ret
);
416 nouveau_hwmon_set_pwm1(struct device
*d
, struct device_attribute
*a
,
417 const char *buf
, size_t count
)
419 struct drm_device
*dev
= dev_get_drvdata(d
);
420 struct nouveau_drm
*drm
= nouveau_drm(dev
);
421 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
425 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
428 ret
= therm
->fan_set(therm
, value
);
435 static SENSOR_DEVICE_ATTR(pwm1
, S_IRUGO
| S_IWUSR
,
436 nouveau_hwmon_get_pwm1
,
437 nouveau_hwmon_set_pwm1
, 0);
440 nouveau_hwmon_get_pwm1_min(struct device
*d
,
441 struct device_attribute
*a
, char *buf
)
443 struct drm_device
*dev
= dev_get_drvdata(d
);
444 struct nouveau_drm
*drm
= nouveau_drm(dev
);
445 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
448 ret
= therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY
);
452 return sprintf(buf
, "%i\n", ret
);
456 nouveau_hwmon_set_pwm1_min(struct device
*d
, struct device_attribute
*a
,
457 const char *buf
, size_t count
)
459 struct drm_device
*dev
= dev_get_drvdata(d
);
460 struct nouveau_drm
*drm
= nouveau_drm(dev
);
461 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
465 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
468 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY
, value
);
475 static SENSOR_DEVICE_ATTR(pwm1_min
, S_IRUGO
| S_IWUSR
,
476 nouveau_hwmon_get_pwm1_min
,
477 nouveau_hwmon_set_pwm1_min
, 0);
480 nouveau_hwmon_get_pwm1_max(struct device
*d
,
481 struct device_attribute
*a
, char *buf
)
483 struct drm_device
*dev
= dev_get_drvdata(d
);
484 struct nouveau_drm
*drm
= nouveau_drm(dev
);
485 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
488 ret
= therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY
);
492 return sprintf(buf
, "%i\n", ret
);
496 nouveau_hwmon_set_pwm1_max(struct device
*d
, struct device_attribute
*a
,
497 const char *buf
, size_t count
)
499 struct drm_device
*dev
= dev_get_drvdata(d
);
500 struct nouveau_drm
*drm
= nouveau_drm(dev
);
501 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
505 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
508 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY
, value
);
515 static SENSOR_DEVICE_ATTR(pwm1_max
, S_IRUGO
| S_IWUSR
,
516 nouveau_hwmon_get_pwm1_max
,
517 nouveau_hwmon_set_pwm1_max
, 0);
519 static struct attribute
*hwmon_default_attributes
[] = {
520 &sensor_dev_attr_name
.dev_attr
.attr
,
521 &sensor_dev_attr_update_rate
.dev_attr
.attr
,
524 static struct attribute
*hwmon_temp_attributes
[] = {
525 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
526 &sensor_dev_attr_temp1_auto_point1_pwm
.dev_attr
.attr
,
527 &sensor_dev_attr_temp1_auto_point1_temp
.dev_attr
.attr
,
528 &sensor_dev_attr_temp1_auto_point1_temp_hyst
.dev_attr
.attr
,
529 &sensor_dev_attr_temp1_max
.dev_attr
.attr
,
530 &sensor_dev_attr_temp1_max_hyst
.dev_attr
.attr
,
531 &sensor_dev_attr_temp1_crit
.dev_attr
.attr
,
532 &sensor_dev_attr_temp1_crit_hyst
.dev_attr
.attr
,
533 &sensor_dev_attr_temp1_emergency
.dev_attr
.attr
,
534 &sensor_dev_attr_temp1_emergency_hyst
.dev_attr
.attr
,
537 static struct attribute
*hwmon_fan_rpm_attributes
[] = {
538 &sensor_dev_attr_fan1_input
.dev_attr
.attr
,
541 static struct attribute
*hwmon_pwm_fan_attributes
[] = {
542 &sensor_dev_attr_pwm1_enable
.dev_attr
.attr
,
543 &sensor_dev_attr_pwm1
.dev_attr
.attr
,
544 &sensor_dev_attr_pwm1_min
.dev_attr
.attr
,
545 &sensor_dev_attr_pwm1_max
.dev_attr
.attr
,
549 static const struct attribute_group hwmon_default_attrgroup
= {
550 .attrs
= hwmon_default_attributes
,
552 static const struct attribute_group hwmon_temp_attrgroup
= {
553 .attrs
= hwmon_temp_attributes
,
555 static const struct attribute_group hwmon_fan_rpm_attrgroup
= {
556 .attrs
= hwmon_fan_rpm_attributes
,
558 static const struct attribute_group hwmon_pwm_fan_attrgroup
= {
559 .attrs
= hwmon_pwm_fan_attributes
,
564 nouveau_hwmon_init(struct drm_device
*dev
)
566 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
567 struct nouveau_drm
*drm
= nouveau_drm(dev
);
568 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
569 struct nouveau_hwmon
*hwmon
;
570 struct device
*hwmon_dev
;
573 hwmon
= drm
->hwmon
= kzalloc(sizeof(*hwmon
), GFP_KERNEL
);
578 if (!therm
|| !therm
->temp_get
|| !therm
->attr_get
|| !therm
->attr_set
)
581 hwmon_dev
= hwmon_device_register(&dev
->pdev
->dev
);
582 if (IS_ERR(hwmon_dev
)) {
583 ret
= PTR_ERR(hwmon_dev
);
584 NV_ERROR(drm
, "Unable to register hwmon device: %d\n", ret
);
587 dev_set_drvdata(hwmon_dev
, dev
);
589 /* set the default attributes */
590 ret
= sysfs_create_group(&hwmon_dev
->kobj
, &hwmon_default_attrgroup
);
594 /* if the card has a working thermal sensor */
595 if (therm
->temp_get(therm
) >= 0) {
596 ret
= sysfs_create_group(&hwmon_dev
->kobj
, &hwmon_temp_attrgroup
);
601 /* if the card has a pwm fan */
602 /*XXX: incorrect, need better detection for this, some boards have
603 * the gpio entries for pwm fan control even when there's no
604 * actual fan connected to it... therm table? */
605 if (therm
->fan_get
&& therm
->fan_get(therm
) >= 0) {
606 ret
= sysfs_create_group(&hwmon_dev
->kobj
,
607 &hwmon_pwm_fan_attrgroup
);
612 /* if the card can read the fan rpm */
613 if (therm
->fan_sense(therm
) >= 0) {
614 ret
= sysfs_create_group(&hwmon_dev
->kobj
,
615 &hwmon_fan_rpm_attrgroup
);
620 hwmon
->hwmon
= hwmon_dev
;
625 NV_ERROR(drm
, "Unable to create some hwmon sysfs files: %d\n", ret
);
626 hwmon_device_unregister(hwmon_dev
);
635 nouveau_hwmon_fini(struct drm_device
*dev
)
637 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
638 struct nouveau_hwmon
*hwmon
= nouveau_hwmon(dev
);
641 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_default_attrgroup
);
642 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_temp_attrgroup
);
643 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_pwm_fan_attrgroup
);
644 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_fan_rpm_attrgroup
);
646 hwmon_device_unregister(hwmon
->hwmon
);
649 nouveau_drm(dev
)->hwmon
= NULL
;