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 }
699