Merge tag 'armsoc-dt64' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[cascardo/linux.git] / drivers / gpu / drm / nouveau / nouveau_hwmon.c
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 <drm/drmP.h>
33
34 #include "nouveau_drm.h"
35 #include "nouveau_hwmon.h"
36
37 #include <nvkm/subdev/volt.h>
38
39 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
40 static ssize_t
41 nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
42 {
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);
47
48         if (temp < 0)
49                 return temp;
50
51         return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
52 }
53 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
54                                                   NULL, 0);
55
56 static ssize_t
57 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
58                                          struct device_attribute *a, char *buf)
59 {
60         return snprintf(buf, PAGE_SIZE, "%d\n", 100);
61 }
62 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
63                           nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
64
65 static ssize_t
66 nouveau_hwmon_temp1_auto_point1_temp(struct device *d,
67                                      struct device_attribute *a, char *buf)
68 {
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);
72
73         return snprintf(buf, PAGE_SIZE, "%d\n",
74               therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000);
75 }
76 static ssize_t
77 nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
78                                          struct device_attribute *a,
79                                          const char *buf, size_t count)
80 {
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);
84         long value;
85
86         if (kstrtol(buf, 10, &value) == -EINVAL)
87                 return count;
88
89         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST,
90                         value / 1000);
91
92         return count;
93 }
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);
97
98 static ssize_t
99 nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d,
100                                           struct device_attribute *a, char *buf)
101 {
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);
105
106         return snprintf(buf, PAGE_SIZE, "%d\n",
107          therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
108 }
109 static ssize_t
110 nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
111                                               struct device_attribute *a,
112                                               const char *buf, size_t count)
113 {
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);
117         long value;
118
119         if (kstrtol(buf, 10, &value) == -EINVAL)
120                 return count;
121
122         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST,
123                         value / 1000);
124
125         return count;
126 }
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);
130
131 static ssize_t
132 nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
133 {
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);
137
138         return snprintf(buf, PAGE_SIZE, "%d\n",
139                therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
140 }
141 static ssize_t
142 nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
143                                                 const char *buf, size_t count)
144 {
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);
148         long value;
149
150         if (kstrtol(buf, 10, &value) == -EINVAL)
151                 return count;
152
153         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
154
155         return count;
156 }
157 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
158                                                   nouveau_hwmon_set_max_temp,
159                                                   0);
160
161 static ssize_t
162 nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
163                             char *buf)
164 {
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);
168
169         return snprintf(buf, PAGE_SIZE, "%d\n",
170           therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
171 }
172 static ssize_t
173 nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
174                                                 const char *buf, size_t count)
175 {
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);
179         long value;
180
181         if (kstrtol(buf, 10, &value) == -EINVAL)
182                 return count;
183
184         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
185                         value / 1000);
186
187         return count;
188 }
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);
192
193 static ssize_t
194 nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
195                                                         char *buf)
196 {
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);
200
201         return snprintf(buf, PAGE_SIZE, "%d\n",
202                therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
203 }
204 static ssize_t
205 nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
206                                                             const char *buf,
207                                                                 size_t count)
208 {
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);
212         long value;
213
214         if (kstrtol(buf, 10, &value) == -EINVAL)
215                 return count;
216
217         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL, value / 1000);
218
219         return count;
220 }
221 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR,
222                                                 nouveau_hwmon_critical_temp,
223                                                 nouveau_hwmon_set_critical_temp,
224                                                 0);
225
226 static ssize_t
227 nouveau_hwmon_critical_temp_hyst(struct device *d, struct device_attribute *a,
228                                                         char *buf)
229 {
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);
233
234         return snprintf(buf, PAGE_SIZE, "%d\n",
235           therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST) * 1000);
236 }
237 static ssize_t
238 nouveau_hwmon_set_critical_temp_hyst(struct device *d,
239                                      struct device_attribute *a,
240                                      const char *buf,
241                                      size_t count)
242 {
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);
246         long value;
247
248         if (kstrtol(buf, 10, &value) == -EINVAL)
249                 return count;
250
251         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST,
252                         value / 1000);
253
254         return count;
255 }
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);
259 static ssize_t
260 nouveau_hwmon_emergency_temp(struct device *d, struct device_attribute *a,
261                                                         char *buf)
262 {
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);
266
267         return snprintf(buf, PAGE_SIZE, "%d\n",
268                therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN) * 1000);
269 }
270 static ssize_t
271 nouveau_hwmon_set_emergency_temp(struct device *d, struct device_attribute *a,
272                                                             const char *buf,
273                                                                 size_t count)
274 {
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);
278         long value;
279
280         if (kstrtol(buf, 10, &value) == -EINVAL)
281                 return count;
282
283         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN, value / 1000);
284
285         return count;
286 }
287 static SENSOR_DEVICE_ATTR(temp1_emergency, S_IRUGO | S_IWUSR,
288                                         nouveau_hwmon_emergency_temp,
289                                         nouveau_hwmon_set_emergency_temp,
290                                         0);
291
292 static ssize_t
293 nouveau_hwmon_emergency_temp_hyst(struct device *d, struct device_attribute *a,
294                                                         char *buf)
295 {
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);
299
300         return snprintf(buf, PAGE_SIZE, "%d\n",
301           therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST) * 1000);
302 }
303 static ssize_t
304 nouveau_hwmon_set_emergency_temp_hyst(struct device *d,
305                                       struct device_attribute *a,
306                                       const char *buf,
307                                       size_t count)
308 {
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);
312         long value;
313
314         if (kstrtol(buf, 10, &value) == -EINVAL)
315                 return count;
316
317         therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST,
318                         value / 1000);
319
320         return count;
321 }
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,
325                                         0);
326
327 static ssize_t nouveau_hwmon_show_name(struct device *dev,
328                                       struct device_attribute *attr,
329                                       char *buf)
330 {
331         return sprintf(buf, "nouveau\n");
332 }
333 static SENSOR_DEVICE_ATTR(name, S_IRUGO, nouveau_hwmon_show_name, NULL, 0);
334
335 static ssize_t nouveau_hwmon_show_update_rate(struct device *dev,
336                                       struct device_attribute *attr,
337                                       char *buf)
338 {
339         return sprintf(buf, "1000\n");
340 }
341 static SENSOR_DEVICE_ATTR(update_rate, S_IRUGO,
342                                                 nouveau_hwmon_show_update_rate,
343                                                 NULL, 0);
344
345 static ssize_t
346 nouveau_hwmon_show_fan1_input(struct device *d, struct device_attribute *attr,
347                               char *buf)
348 {
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);
352
353         return snprintf(buf, PAGE_SIZE, "%d\n", nvkm_therm_fan_sense(therm));
354 }
355 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, nouveau_hwmon_show_fan1_input,
356                           NULL, 0);
357
358  static ssize_t
359 nouveau_hwmon_get_pwm1_enable(struct device *d,
360                            struct device_attribute *a, char *buf)
361 {
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);
365         int ret;
366
367         ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
368         if (ret < 0)
369                 return ret;
370
371         return sprintf(buf, "%i\n", ret);
372 }
373
374 static ssize_t
375 nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a,
376                            const char *buf, size_t count)
377 {
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);
381         long value;
382         int ret;
383
384         ret = kstrtol(buf, 10, &value);
385         if (ret)
386                 return ret;
387
388         ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, value);
389         if (ret)
390                 return ret;
391         else
392                 return count;
393 }
394 static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
395                           nouveau_hwmon_get_pwm1_enable,
396                           nouveau_hwmon_set_pwm1_enable, 0);
397
398 static ssize_t
399 nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf)
400 {
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);
404         int ret;
405
406         ret = therm->fan_get(therm);
407         if (ret < 0)
408                 return ret;
409
410         return sprintf(buf, "%i\n", ret);
411 }
412
413 static ssize_t
414 nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a,
415                        const char *buf, size_t count)
416 {
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);
420         int ret = -ENODEV;
421         long value;
422
423         if (kstrtol(buf, 10, &value) == -EINVAL)
424                 return -EINVAL;
425
426         ret = therm->fan_set(therm, value);
427         if (ret)
428                 return ret;
429
430         return count;
431 }
432
433 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR,
434                           nouveau_hwmon_get_pwm1,
435                           nouveau_hwmon_set_pwm1, 0);
436
437 static ssize_t
438 nouveau_hwmon_get_pwm1_min(struct device *d,
439                            struct device_attribute *a, char *buf)
440 {
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);
444         int ret;
445
446         ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY);
447         if (ret < 0)
448                 return ret;
449
450         return sprintf(buf, "%i\n", ret);
451 }
452
453 static ssize_t
454 nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
455                            const char *buf, size_t count)
456 {
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);
460         long value;
461         int ret;
462
463         if (kstrtol(buf, 10, &value) == -EINVAL)
464                 return -EINVAL;
465
466         ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY, value);
467         if (ret < 0)
468                 return ret;
469
470         return count;
471 }
472
473 static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
474                           nouveau_hwmon_get_pwm1_min,
475                           nouveau_hwmon_set_pwm1_min, 0);
476
477 static ssize_t
478 nouveau_hwmon_get_pwm1_max(struct device *d,
479                            struct device_attribute *a, char *buf)
480 {
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);
484         int ret;
485
486         ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY);
487         if (ret < 0)
488                 return ret;
489
490         return sprintf(buf, "%i\n", ret);
491 }
492
493 static ssize_t
494 nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
495                            const char *buf, size_t count)
496 {
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);
500         long value;
501         int ret;
502
503         if (kstrtol(buf, 10, &value) == -EINVAL)
504                 return -EINVAL;
505
506         ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY, value);
507         if (ret < 0)
508                 return ret;
509
510         return count;
511 }
512
513 static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
514                           nouveau_hwmon_get_pwm1_max,
515                           nouveau_hwmon_set_pwm1_max, 0);
516
517 static ssize_t
518 nouveau_hwmon_get_in0_input(struct device *d,
519                             struct device_attribute *a, char *buf)
520 {
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);
524         int ret;
525
526         ret = nvkm_volt_get(volt);
527         if (ret < 0)
528                 return ret;
529
530         return sprintf(buf, "%i\n", ret / 1000);
531 }
532
533 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO,
534                           nouveau_hwmon_get_in0_input, NULL, 0);
535
536 static ssize_t
537 nouveau_hwmon_get_in0_label(struct device *d,
538                             struct device_attribute *a, char *buf)
539 {
540         return sprintf(buf, "GPU core\n");
541 }
542
543 static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO,
544                           nouveau_hwmon_get_in0_label, NULL, 0);
545
546 static struct attribute *hwmon_default_attributes[] = {
547         &sensor_dev_attr_name.dev_attr.attr,
548         &sensor_dev_attr_update_rate.dev_attr.attr,
549         NULL
550 };
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,
562         NULL
563 };
564 static struct attribute *hwmon_fan_rpm_attributes[] = {
565         &sensor_dev_attr_fan1_input.dev_attr.attr,
566         NULL
567 };
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,
573         NULL
574 };
575
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,
579         NULL
580 };
581
582 static const struct attribute_group hwmon_default_attrgroup = {
583         .attrs = hwmon_default_attributes,
584 };
585 static const struct attribute_group hwmon_temp_attrgroup = {
586         .attrs = hwmon_temp_attributes,
587 };
588 static const struct attribute_group hwmon_fan_rpm_attrgroup = {
589         .attrs = hwmon_fan_rpm_attributes,
590 };
591 static const struct attribute_group hwmon_pwm_fan_attrgroup = {
592         .attrs = hwmon_pwm_fan_attributes,
593 };
594 static const struct attribute_group hwmon_in0_attrgroup = {
595         .attrs = hwmon_in0_attributes,
596 };
597 #endif
598
599 int
600 nouveau_hwmon_init(struct drm_device *dev)
601 {
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;
608         int ret = 0;
609
610         hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
611         if (!hwmon)
612                 return -ENOMEM;
613         hwmon->dev = dev;
614
615         if (!therm || !therm->attr_get || !therm->attr_set)
616                 return -ENODEV;
617
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);
622                 return ret;
623         }
624         dev_set_drvdata(hwmon_dev, dev);
625
626         /* set the default attributes */
627         ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_default_attrgroup);
628         if (ret)
629                 goto error;
630
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);
634                 if (ret)
635                         goto error;
636         }
637
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);
645                 if (ret)
646                         goto error;
647         }
648
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);
653                 if (ret)
654                         goto error;
655         }
656
657         if (volt && nvkm_volt_get(volt) >= 0) {
658                 ret = sysfs_create_group(&hwmon_dev->kobj,
659                                          &hwmon_in0_attrgroup);
660
661                 if (ret)
662                         goto error;
663         }
664
665         hwmon->hwmon = hwmon_dev;
666
667         return 0;
668
669 error:
670         NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret);
671         hwmon_device_unregister(hwmon_dev);
672         hwmon->hwmon = NULL;
673         return ret;
674 #else
675         return 0;
676 #endif
677 }
678
679 void
680 nouveau_hwmon_fini(struct drm_device *dev)
681 {
682 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
683         struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
684
685         if (hwmon->hwmon) {
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);
691
692                 hwmon_device_unregister(hwmon->hwmon);
693         }
694
695         nouveau_drm(dev)->hwmon = NULL;
696         kfree(hwmon);
697 #endif
698 }