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 if (strict_strtol(buf
, 10, &value
) == -EINVAL
)
389 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MODE
, value
);
395 static SENSOR_DEVICE_ATTR(pwm1_enable
, S_IRUGO
| S_IWUSR
,
396 nouveau_hwmon_get_pwm1_enable
,
397 nouveau_hwmon_set_pwm1_enable
, 0);
400 nouveau_hwmon_get_pwm1(struct device
*d
, struct device_attribute
*a
, char *buf
)
402 struct drm_device
*dev
= dev_get_drvdata(d
);
403 struct nouveau_drm
*drm
= nouveau_drm(dev
);
404 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
407 ret
= therm
->fan_get(therm
);
411 return sprintf(buf
, "%i\n", ret
);
415 nouveau_hwmon_set_pwm1(struct device
*d
, struct device_attribute
*a
,
416 const char *buf
, size_t count
)
418 struct drm_device
*dev
= dev_get_drvdata(d
);
419 struct nouveau_drm
*drm
= nouveau_drm(dev
);
420 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
424 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
427 ret
= therm
->fan_set(therm
, value
);
434 static SENSOR_DEVICE_ATTR(pwm1
, S_IRUGO
| S_IWUSR
,
435 nouveau_hwmon_get_pwm1
,
436 nouveau_hwmon_set_pwm1
, 0);
439 nouveau_hwmon_get_pwm1_min(struct device
*d
,
440 struct device_attribute
*a
, char *buf
)
442 struct drm_device
*dev
= dev_get_drvdata(d
);
443 struct nouveau_drm
*drm
= nouveau_drm(dev
);
444 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
447 ret
= therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY
);
451 return sprintf(buf
, "%i\n", ret
);
455 nouveau_hwmon_set_pwm1_min(struct device
*d
, struct device_attribute
*a
,
456 const char *buf
, size_t count
)
458 struct drm_device
*dev
= dev_get_drvdata(d
);
459 struct nouveau_drm
*drm
= nouveau_drm(dev
);
460 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
464 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
467 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY
, value
);
474 static SENSOR_DEVICE_ATTR(pwm1_min
, S_IRUGO
| S_IWUSR
,
475 nouveau_hwmon_get_pwm1_min
,
476 nouveau_hwmon_set_pwm1_min
, 0);
479 nouveau_hwmon_get_pwm1_max(struct device
*d
,
480 struct device_attribute
*a
, char *buf
)
482 struct drm_device
*dev
= dev_get_drvdata(d
);
483 struct nouveau_drm
*drm
= nouveau_drm(dev
);
484 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
487 ret
= therm
->attr_get(therm
, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY
);
491 return sprintf(buf
, "%i\n", ret
);
495 nouveau_hwmon_set_pwm1_max(struct device
*d
, struct device_attribute
*a
,
496 const char *buf
, size_t count
)
498 struct drm_device
*dev
= dev_get_drvdata(d
);
499 struct nouveau_drm
*drm
= nouveau_drm(dev
);
500 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
504 if (kstrtol(buf
, 10, &value
) == -EINVAL
)
507 ret
= therm
->attr_set(therm
, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY
, value
);
514 static SENSOR_DEVICE_ATTR(pwm1_max
, S_IRUGO
| S_IWUSR
,
515 nouveau_hwmon_get_pwm1_max
,
516 nouveau_hwmon_set_pwm1_max
, 0);
518 static struct attribute
*hwmon_default_attributes
[] = {
519 &sensor_dev_attr_name
.dev_attr
.attr
,
520 &sensor_dev_attr_update_rate
.dev_attr
.attr
,
523 static struct attribute
*hwmon_temp_attributes
[] = {
524 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
525 &sensor_dev_attr_temp1_auto_point1_pwm
.dev_attr
.attr
,
526 &sensor_dev_attr_temp1_auto_point1_temp
.dev_attr
.attr
,
527 &sensor_dev_attr_temp1_auto_point1_temp_hyst
.dev_attr
.attr
,
528 &sensor_dev_attr_temp1_max
.dev_attr
.attr
,
529 &sensor_dev_attr_temp1_max_hyst
.dev_attr
.attr
,
530 &sensor_dev_attr_temp1_crit
.dev_attr
.attr
,
531 &sensor_dev_attr_temp1_crit_hyst
.dev_attr
.attr
,
532 &sensor_dev_attr_temp1_emergency
.dev_attr
.attr
,
533 &sensor_dev_attr_temp1_emergency_hyst
.dev_attr
.attr
,
536 static struct attribute
*hwmon_fan_rpm_attributes
[] = {
537 &sensor_dev_attr_fan1_input
.dev_attr
.attr
,
540 static struct attribute
*hwmon_pwm_fan_attributes
[] = {
541 &sensor_dev_attr_pwm1_enable
.dev_attr
.attr
,
542 &sensor_dev_attr_pwm1
.dev_attr
.attr
,
543 &sensor_dev_attr_pwm1_min
.dev_attr
.attr
,
544 &sensor_dev_attr_pwm1_max
.dev_attr
.attr
,
548 static const struct attribute_group hwmon_default_attrgroup
= {
549 .attrs
= hwmon_default_attributes
,
551 static const struct attribute_group hwmon_temp_attrgroup
= {
552 .attrs
= hwmon_temp_attributes
,
554 static const struct attribute_group hwmon_fan_rpm_attrgroup
= {
555 .attrs
= hwmon_fan_rpm_attributes
,
557 static const struct attribute_group hwmon_pwm_fan_attrgroup
= {
558 .attrs
= hwmon_pwm_fan_attributes
,
563 nouveau_hwmon_init(struct drm_device
*dev
)
565 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
566 struct nouveau_drm
*drm
= nouveau_drm(dev
);
567 struct nouveau_therm
*therm
= nouveau_therm(drm
->device
);
568 struct nouveau_hwmon
*hwmon
;
569 struct device
*hwmon_dev
;
572 hwmon
= drm
->hwmon
= kzalloc(sizeof(*hwmon
), GFP_KERNEL
);
577 if (!therm
|| !therm
->temp_get
|| !therm
->attr_get
|| !therm
->attr_set
)
580 hwmon_dev
= hwmon_device_register(&dev
->pdev
->dev
);
581 if (IS_ERR(hwmon_dev
)) {
582 ret
= PTR_ERR(hwmon_dev
);
583 NV_ERROR(drm
, "Unable to register hwmon device: %d\n", ret
);
586 dev_set_drvdata(hwmon_dev
, dev
);
588 /* set the default attributes */
589 ret
= sysfs_create_group(&hwmon_dev
->kobj
, &hwmon_default_attrgroup
);
595 /* if the card has a working thermal sensor */
596 if (therm
->temp_get(therm
) >= 0) {
597 ret
= sysfs_create_group(&hwmon_dev
->kobj
, &hwmon_temp_attrgroup
);
604 /* if the card has a pwm fan */
605 /*XXX: incorrect, need better detection for this, some boards have
606 * the gpio entries for pwm fan control even when there's no
607 * actual fan connected to it... therm table? */
608 if (therm
->fan_get
&& therm
->fan_get(therm
) >= 0) {
609 ret
= sysfs_create_group(&hwmon_dev
->kobj
,
610 &hwmon_pwm_fan_attrgroup
);
615 /* if the card can read the fan rpm */
616 if (therm
->fan_sense(therm
) >= 0) {
617 ret
= sysfs_create_group(&hwmon_dev
->kobj
,
618 &hwmon_fan_rpm_attrgroup
);
623 hwmon
->hwmon
= hwmon_dev
;
628 NV_ERROR(drm
, "Unable to create some hwmon sysfs files: %d\n", ret
);
629 hwmon_device_unregister(hwmon_dev
);
638 nouveau_hwmon_fini(struct drm_device
*dev
)
640 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
641 struct nouveau_hwmon
*hwmon
= nouveau_hwmon(dev
);
644 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_default_attrgroup
);
645 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_temp_attrgroup
);
646 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_pwm_fan_attrgroup
);
647 sysfs_remove_group(&hwmon
->hwmon
->kobj
, &hwmon_fan_rpm_attrgroup
);
649 hwmon_device_unregister(hwmon
->hwmon
);
652 nouveau_drm(dev
)->hwmon
= NULL
;