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