Merge tag 'for-linus-6.9-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.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 "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 sysfs_emit(buf, "%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 sysfs_emit(buf, "%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 sysfs_emit(buf, "%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 struct hwmon_channel_info * const nouveau_info[] = {
215         HWMON_CHANNEL_INFO(chip,
216                            HWMON_C_UPDATE_INTERVAL),
217         HWMON_CHANNEL_INFO(temp,
218                            HWMON_T_INPUT |
219                            HWMON_T_MAX | HWMON_T_MAX_HYST |
220                            HWMON_T_CRIT | HWMON_T_CRIT_HYST |
221                            HWMON_T_EMERGENCY | HWMON_T_EMERGENCY_HYST),
222         HWMON_CHANNEL_INFO(fan,
223                            HWMON_F_INPUT),
224         HWMON_CHANNEL_INFO(in,
225                            HWMON_I_INPUT |
226                            HWMON_I_MIN | HWMON_I_MAX |
227                            HWMON_I_LABEL),
228         HWMON_CHANNEL_INFO(pwm,
229                            HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
230         HWMON_CHANNEL_INFO(power,
231                            HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT),
232         NULL
233 };
234
235 static umode_t
236 nouveau_chip_is_visible(const void *data, u32 attr, int channel)
237 {
238         switch (attr) {
239         case hwmon_chip_update_interval:
240                 return 0444;
241         default:
242                 return 0;
243         }
244 }
245
246 static umode_t
247 nouveau_power_is_visible(const void *data, u32 attr, int channel)
248 {
249         struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
250         struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
251
252         if (!iccsense || !iccsense->data_valid || list_empty(&iccsense->rails))
253                 return 0;
254
255         switch (attr) {
256         case hwmon_power_input:
257                 return 0444;
258         case hwmon_power_max:
259                 if (iccsense->power_w_max)
260                         return 0444;
261                 return 0;
262         case hwmon_power_crit:
263                 if (iccsense->power_w_crit)
264                         return 0444;
265                 return 0;
266         default:
267                 return 0;
268         }
269 }
270
271 static umode_t
272 nouveau_temp_is_visible(const void *data, u32 attr, int channel)
273 {
274         struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
275         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
276
277         if (!therm || !therm->attr_get || nvkm_therm_temp_get(therm) < 0)
278                 return 0;
279
280         switch (attr) {
281         case hwmon_temp_input:
282                 return 0444;
283         case hwmon_temp_max:
284         case hwmon_temp_max_hyst:
285         case hwmon_temp_crit:
286         case hwmon_temp_crit_hyst:
287         case hwmon_temp_emergency:
288         case hwmon_temp_emergency_hyst:
289                 return 0644;
290         default:
291                 return 0;
292         }
293 }
294
295 static umode_t
296 nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
297 {
298         struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
299         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
300
301         if (!therm || !therm->attr_get || !therm->fan_get ||
302             therm->fan_get(therm) < 0)
303                 return 0;
304
305         switch (attr) {
306         case hwmon_pwm_enable:
307         case hwmon_pwm_input:
308                 return 0644;
309         default:
310                 return 0;
311         }
312 }
313
314 static umode_t
315 nouveau_input_is_visible(const void *data, u32 attr, int channel)
316 {
317         struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
318         struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
319
320         if (!volt || nvkm_volt_get(volt) < 0)
321                 return 0;
322
323         switch (attr) {
324         case hwmon_in_input:
325         case hwmon_in_label:
326         case hwmon_in_min:
327         case hwmon_in_max:
328                 return 0444;
329         default:
330                 return 0;
331         }
332 }
333
334 static umode_t
335 nouveau_fan_is_visible(const void *data, u32 attr, int channel)
336 {
337         struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
338         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
339
340         if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
341                 return 0;
342
343         switch (attr) {
344         case hwmon_fan_input:
345                 return 0444;
346         default:
347                 return 0;
348         }
349 }
350
351 static int
352 nouveau_chip_read(struct device *dev, u32 attr, int channel, long *val)
353 {
354         switch (attr) {
355         case hwmon_chip_update_interval:
356                 *val = 1000;
357                 break;
358         default:
359                 return -EOPNOTSUPP;
360         }
361
362         return 0;
363 }
364
365 static int
366 nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
367 {
368         struct drm_device *drm_dev = dev_get_drvdata(dev);
369         struct nouveau_drm *drm = nouveau_drm(drm_dev);
370         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
371         int ret;
372
373         if (!therm || !therm->attr_get)
374                 return -EOPNOTSUPP;
375
376         switch (attr) {
377         case hwmon_temp_input:
378                 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
379                         return -EINVAL;
380                 ret = nvkm_therm_temp_get(therm);
381                 *val = ret < 0 ? ret : (ret * 1000);
382                 break;
383         case hwmon_temp_max:
384                 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
385                                         * 1000;
386                 break;
387         case hwmon_temp_max_hyst:
388                 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST)
389                                         * 1000;
390                 break;
391         case hwmon_temp_crit:
392                 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL)
393                                         * 1000;
394                 break;
395         case hwmon_temp_crit_hyst:
396                 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST)
397                                         * 1000;
398                 break;
399         case hwmon_temp_emergency:
400                 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN)
401                                         * 1000;
402                 break;
403         case hwmon_temp_emergency_hyst:
404                 *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST)
405                                         * 1000;
406                 break;
407         default:
408                 return -EOPNOTSUPP;
409         }
410
411         return 0;
412 }
413
414 static int
415 nouveau_fan_read(struct device *dev, u32 attr, int channel, long *val)
416 {
417         struct drm_device *drm_dev = dev_get_drvdata(dev);
418         struct nouveau_drm *drm = nouveau_drm(drm_dev);
419         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
420
421         if (!therm)
422                 return -EOPNOTSUPP;
423
424         switch (attr) {
425         case hwmon_fan_input:
426                 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
427                         return -EINVAL;
428                 *val = nvkm_therm_fan_sense(therm);
429                 break;
430         default:
431                 return -EOPNOTSUPP;
432         }
433
434         return 0;
435 }
436
437 static int
438 nouveau_in_read(struct device *dev, u32 attr, int channel, long *val)
439 {
440         struct drm_device *drm_dev = dev_get_drvdata(dev);
441         struct nouveau_drm *drm = nouveau_drm(drm_dev);
442         struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
443         int ret;
444
445         if (!volt)
446                 return -EOPNOTSUPP;
447
448         switch (attr) {
449         case hwmon_in_input:
450                 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
451                         return -EINVAL;
452                 ret = nvkm_volt_get(volt);
453                 *val = ret < 0 ? ret : (ret / 1000);
454                 break;
455         case hwmon_in_min:
456                 *val = volt->min_uv > 0 ? (volt->min_uv / 1000) : -ENODEV;
457                 break;
458         case hwmon_in_max:
459                 *val = volt->max_uv > 0 ? (volt->max_uv / 1000) : -ENODEV;
460                 break;
461         default:
462                 return -EOPNOTSUPP;
463         }
464
465         return 0;
466 }
467
468 static int
469 nouveau_pwm_read(struct device *dev, u32 attr, int channel, long *val)
470 {
471         struct drm_device *drm_dev = dev_get_drvdata(dev);
472         struct nouveau_drm *drm = nouveau_drm(drm_dev);
473         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
474
475         if (!therm || !therm->attr_get || !therm->fan_get)
476                 return -EOPNOTSUPP;
477
478         switch (attr) {
479         case hwmon_pwm_enable:
480                 *val = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
481                 break;
482         case hwmon_pwm_input:
483                 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
484                         return -EINVAL;
485                 *val = therm->fan_get(therm);
486                 break;
487         default:
488                 return -EOPNOTSUPP;
489         }
490
491         return 0;
492 }
493
494 static int
495 nouveau_power_read(struct device *dev, u32 attr, int channel, long *val)
496 {
497         struct drm_device *drm_dev = dev_get_drvdata(dev);
498         struct nouveau_drm *drm = nouveau_drm(drm_dev);
499         struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
500
501         if (!iccsense)
502                 return -EOPNOTSUPP;
503
504         switch (attr) {
505         case hwmon_power_input:
506                 if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
507                         return -EINVAL;
508                 *val = nvkm_iccsense_read_all(iccsense);
509                 break;
510         case hwmon_power_max:
511                 *val = iccsense->power_w_max;
512                 break;
513         case hwmon_power_crit:
514                 *val = iccsense->power_w_crit;
515                 break;
516         default:
517                 return -EOPNOTSUPP;
518         }
519
520         return 0;
521 }
522
523 static int
524 nouveau_temp_write(struct device *dev, u32 attr, int channel, long val)
525 {
526         struct drm_device *drm_dev = dev_get_drvdata(dev);
527         struct nouveau_drm *drm = nouveau_drm(drm_dev);
528         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
529
530         if (!therm || !therm->attr_set)
531                 return -EOPNOTSUPP;
532
533         switch (attr) {
534         case hwmon_temp_max:
535                 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK,
536                                         val / 1000);
537         case hwmon_temp_max_hyst:
538                 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
539                                         val / 1000);
540         case hwmon_temp_crit:
541                 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL,
542                                         val / 1000);
543         case hwmon_temp_crit_hyst:
544                 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST,
545                                         val / 1000);
546         case hwmon_temp_emergency:
547                 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN,
548                                         val / 1000);
549         case hwmon_temp_emergency_hyst:
550                 return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST,
551                                         val / 1000);
552         default:
553                 return -EOPNOTSUPP;
554         }
555 }
556
557 static int
558 nouveau_pwm_write(struct device *dev, u32 attr, int channel, long val)
559 {
560         struct drm_device *drm_dev = dev_get_drvdata(dev);
561         struct nouveau_drm *drm = nouveau_drm(drm_dev);
562         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
563
564         if (!therm || !therm->attr_set)
565                 return -EOPNOTSUPP;
566
567         switch (attr) {
568         case hwmon_pwm_input:
569                 return therm->fan_set(therm, val);
570         case hwmon_pwm_enable:
571                 return therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, val);
572         default:
573                 return -EOPNOTSUPP;
574         }
575 }
576
577 static umode_t
578 nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
579                         int channel)
580 {
581         switch (type) {
582         case hwmon_chip:
583                 return nouveau_chip_is_visible(data, attr, channel);
584         case hwmon_temp:
585                 return nouveau_temp_is_visible(data, attr, channel);
586         case hwmon_fan:
587                 return nouveau_fan_is_visible(data, attr, channel);
588         case hwmon_in:
589                 return nouveau_input_is_visible(data, attr, channel);
590         case hwmon_pwm:
591                 return nouveau_pwm_is_visible(data, attr, channel);
592         case hwmon_power:
593                 return nouveau_power_is_visible(data, attr, channel);
594         default:
595                 return 0;
596         }
597 }
598
599 static const char input_label[] = "GPU core";
600
601 static int
602 nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
603                     int channel, const char **buf)
604 {
605         if (type == hwmon_in && attr == hwmon_in_label) {
606                 *buf = input_label;
607                 return 0;
608         }
609
610         return -EOPNOTSUPP;
611 }
612
613 static int
614 nouveau_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
615                                                         int channel, long *val)
616 {
617         switch (type) {
618         case hwmon_chip:
619                 return nouveau_chip_read(dev, attr, channel, val);
620         case hwmon_temp:
621                 return nouveau_temp_read(dev, attr, channel, val);
622         case hwmon_fan:
623                 return nouveau_fan_read(dev, attr, channel, val);
624         case hwmon_in:
625                 return nouveau_in_read(dev, attr, channel, val);
626         case hwmon_pwm:
627                 return nouveau_pwm_read(dev, attr, channel, val);
628         case hwmon_power:
629                 return nouveau_power_read(dev, attr, channel, val);
630         default:
631                 return -EOPNOTSUPP;
632         }
633 }
634
635 static int
636 nouveau_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
637                                                         int channel, long val)
638 {
639         switch (type) {
640         case hwmon_temp:
641                 return nouveau_temp_write(dev, attr, channel, val);
642         case hwmon_pwm:
643                 return nouveau_pwm_write(dev, attr, channel, val);
644         default:
645                 return -EOPNOTSUPP;
646         }
647 }
648
649 static const struct hwmon_ops nouveau_hwmon_ops = {
650         .is_visible = nouveau_is_visible,
651         .read = nouveau_read,
652         .read_string = nouveau_read_string,
653         .write = nouveau_write,
654 };
655
656 static const struct hwmon_chip_info nouveau_chip_info = {
657         .ops = &nouveau_hwmon_ops,
658         .info = nouveau_info,
659 };
660 #endif
661
662 int
663 nouveau_hwmon_init(struct drm_device *dev)
664 {
665 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
666         struct nouveau_drm *drm = nouveau_drm(dev);
667         struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
668         struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
669         struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
670         const struct attribute_group *special_groups[N_ATTR_GROUPS];
671         struct nouveau_hwmon *hwmon;
672         struct device *hwmon_dev;
673         int ret = 0;
674         int i = 0;
675
676         if (!iccsense && !therm && !volt) {
677                 NV_DEBUG(drm, "Skipping hwmon registration\n");
678                 return 0;
679         }
680
681         hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
682         if (!hwmon)
683                 return -ENOMEM;
684         hwmon->dev = dev;
685
686         if (therm && therm->attr_get && therm->attr_set) {
687                 if (nvkm_therm_temp_get(therm) >= 0)
688                         special_groups[i++] = &temp1_auto_point_sensor_group;
689                 if (therm->fan_get && therm->fan_get(therm) >= 0)
690                         special_groups[i++] = &pwm_fan_sensor_group;
691         }
692
693         special_groups[i] = NULL;
694         hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
695                                                         &nouveau_chip_info,
696                                                         special_groups);
697         if (IS_ERR(hwmon_dev)) {
698                 ret = PTR_ERR(hwmon_dev);
699                 NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
700                 return ret;
701         }
702
703         hwmon->hwmon = hwmon_dev;
704         return 0;
705 #else
706         return 0;
707 #endif
708 }
709
710 void
711 nouveau_hwmon_fini(struct drm_device *dev)
712 {
713 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
714         struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
715
716         if (!hwmon)
717                 return;
718
719         if (hwmon->hwmon)
720                 hwmon_device_unregister(hwmon->hwmon);
721
722         nouveau_drm(dev)->hwmon = NULL;
723         kfree(hwmon);
724 #endif
725 }