nouveau_hwmon.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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. #ifdef CONFIG_ACPI
  25. #include <linux/acpi.h>
  26. #endif
  27. #include <linux/power_supply.h>
  28. #include <linux/hwmon.h>
  29. #include <linux/hwmon-sysfs.h>
  30. #include "nouveau_drv.h"
  31. #include "nouveau_hwmon.h"
  32. #include <nvkm/subdev/iccsense.h>
  33. #include <nvkm/subdev/volt.h>
  34. #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
  35. static ssize_t
  36. nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
  37. struct device_attribute *a, char *buf)
  38. {
  39. return snprintf(buf, PAGE_SIZE, "%d\n", 100);
  40. }
  41. static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  42. nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
  43. static ssize_t
  44. nouveau_hwmon_temp1_auto_point1_temp(struct device *d,
  45. struct device_attribute *a, char *buf)
  46. {
  47. struct drm_device *dev = dev_get_drvdata(d);
  48. struct nouveau_drm *drm = nouveau_drm(dev);
  49. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  50. return snprintf(buf, PAGE_SIZE, "%d\n",
  51. therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000);
  52. }
  53. static ssize_t
  54. nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
  55. struct device_attribute *a,
  56. const char *buf, size_t count)
  57. {
  58. struct drm_device *dev = dev_get_drvdata(d);
  59. struct nouveau_drm *drm = nouveau_drm(dev);
  60. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  61. long value;
  62. if (kstrtol(buf, 10, &value))
  63. return -EINVAL;
  64. therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST,
  65. value / 1000);
  66. return count;
  67. }
  68. static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  69. nouveau_hwmon_temp1_auto_point1_temp,
  70. nouveau_hwmon_set_temp1_auto_point1_temp, 0);
  71. static ssize_t
  72. nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d,
  73. struct device_attribute *a, char *buf)
  74. {
  75. struct drm_device *dev = dev_get_drvdata(d);
  76. struct nouveau_drm *drm = nouveau_drm(dev);
  77. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  78. return snprintf(buf, PAGE_SIZE, "%d\n",
  79. therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
  80. }
  81. static ssize_t
  82. nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
  83. struct device_attribute *a,
  84. const char *buf, size_t count)
  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. long value;
  90. if (kstrtol(buf, 10, &value))
  91. return -EINVAL;
  92. therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST,
  93. value / 1000);
  94. return count;
  95. }
  96. static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  97. nouveau_hwmon_temp1_auto_point1_temp_hyst,
  98. nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
  99. static ssize_t
  100. nouveau_hwmon_get_pwm1_max(struct device *d,
  101. struct device_attribute *a, char *buf)
  102. {
  103. struct drm_device *dev = dev_get_drvdata(d);
  104. struct nouveau_drm *drm = nouveau_drm(dev);
  105. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  106. int ret;
  107. ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY);
  108. if (ret < 0)
  109. return ret;
  110. return sprintf(buf, "%i\n", ret);
  111. }
  112. static ssize_t
  113. nouveau_hwmon_get_pwm1_min(struct device *d,
  114. struct device_attribute *a, char *buf)
  115. {
  116. struct drm_device *dev = dev_get_drvdata(d);
  117. struct nouveau_drm *drm = nouveau_drm(dev);
  118. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  119. int ret;
  120. ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY);
  121. if (ret < 0)
  122. return ret;
  123. return sprintf(buf, "%i\n", ret);
  124. }
  125. static ssize_t
  126. nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
  127. const char *buf, size_t count)
  128. {
  129. struct drm_device *dev = dev_get_drvdata(d);
  130. struct nouveau_drm *drm = nouveau_drm(dev);
  131. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  132. long value;
  133. int ret;
  134. if (kstrtol(buf, 10, &value))
  135. return -EINVAL;
  136. ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY, value);
  137. if (ret < 0)
  138. return ret;
  139. return count;
  140. }
  141. static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  142. nouveau_hwmon_get_pwm1_min,
  143. nouveau_hwmon_set_pwm1_min, 0);
  144. static ssize_t
  145. nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
  146. const char *buf, size_t count)
  147. {
  148. struct drm_device *dev = dev_get_drvdata(d);
  149. struct nouveau_drm *drm = nouveau_drm(dev);
  150. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  151. long value;
  152. int ret;
  153. if (kstrtol(buf, 10, &value))
  154. return -EINVAL;
  155. ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY, value);
  156. if (ret < 0)
  157. return ret;
  158. return count;
  159. }
  160. static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  161. nouveau_hwmon_get_pwm1_max,
  162. nouveau_hwmon_set_pwm1_max, 0);
  163. static struct attribute *pwm_fan_sensor_attrs[] = {
  164. &sensor_dev_attr_pwm1_min.dev_attr.attr,
  165. &sensor_dev_attr_pwm1_max.dev_attr.attr,
  166. NULL
  167. };
  168. static const struct attribute_group pwm_fan_sensor_group = {
  169. .attrs = pwm_fan_sensor_attrs,
  170. };
  171. static struct attribute *temp1_auto_point_sensor_attrs[] = {
  172. &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
  173. &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
  174. &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
  175. NULL
  176. };
  177. static const struct attribute_group temp1_auto_point_sensor_group = {
  178. .attrs = temp1_auto_point_sensor_attrs,
  179. };
  180. #define N_ATTR_GROUPS 3
  181. static const struct hwmon_channel_info *nouveau_info[] = {
  182. HWMON_CHANNEL_INFO(chip,
  183. HWMON_C_UPDATE_INTERVAL),
  184. HWMON_CHANNEL_INFO(temp,
  185. HWMON_T_INPUT |
  186. HWMON_T_MAX | HWMON_T_MAX_HYST |
  187. HWMON_T_CRIT | HWMON_T_CRIT_HYST |
  188. HWMON_T_EMERGENCY | HWMON_T_EMERGENCY_HYST),
  189. HWMON_CHANNEL_INFO(fan,
  190. HWMON_F_INPUT),
  191. HWMON_CHANNEL_INFO(in,
  192. HWMON_I_INPUT |
  193. HWMON_I_MIN | HWMON_I_MAX |
  194. HWMON_I_LABEL),
  195. HWMON_CHANNEL_INFO(pwm,
  196. HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
  197. HWMON_CHANNEL_INFO(power,
  198. HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT),
  199. NULL
  200. };
  201. static umode_t
  202. nouveau_chip_is_visible(const void *data, u32 attr, int channel)
  203. {
  204. switch (attr) {
  205. case hwmon_chip_update_interval:
  206. return 0444;
  207. default:
  208. return 0;
  209. }
  210. }
  211. static umode_t
  212. nouveau_power_is_visible(const void *data, u32 attr, int channel)
  213. {
  214. struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
  215. struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
  216. if (!iccsense || !iccsense->data_valid || list_empty(&iccsense->rails))
  217. return 0;
  218. switch (attr) {
  219. case hwmon_power_input:
  220. return 0444;
  221. case hwmon_power_max:
  222. if (iccsense->power_w_max)
  223. return 0444;
  224. return 0;
  225. case hwmon_power_crit:
  226. if (iccsense->power_w_crit)
  227. return 0444;
  228. return 0;
  229. default:
  230. return 0;
  231. }
  232. }
  233. static umode_t
  234. nouveau_temp_is_visible(const void *data, u32 attr, int channel)
  235. {
  236. struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
  237. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  238. if (!therm || !therm->attr_get || nvkm_therm_temp_get(therm) < 0)
  239. return 0;
  240. switch (attr) {
  241. case hwmon_temp_input:
  242. return 0444;
  243. case hwmon_temp_max:
  244. case hwmon_temp_max_hyst:
  245. case hwmon_temp_crit:
  246. case hwmon_temp_crit_hyst:
  247. case hwmon_temp_emergency:
  248. case hwmon_temp_emergency_hyst:
  249. return 0644;
  250. default:
  251. return 0;
  252. }
  253. }
  254. static umode_t
  255. nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
  256. {
  257. struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
  258. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  259. if (!therm || !therm->attr_get || !therm->fan_get ||
  260. therm->fan_get(therm) < 0)
  261. return 0;
  262. switch (attr) {
  263. case hwmon_pwm_enable:
  264. case hwmon_pwm_input:
  265. return 0644;
  266. default:
  267. return 0;
  268. }
  269. }
  270. static umode_t
  271. nouveau_input_is_visible(const void *data, u32 attr, int channel)
  272. {
  273. struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
  274. struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
  275. if (!volt || nvkm_volt_get(volt) < 0)
  276. return 0;
  277. switch (attr) {
  278. case hwmon_in_input:
  279. case hwmon_in_label:
  280. case hwmon_in_min:
  281. case hwmon_in_max:
  282. return 0444;
  283. default:
  284. return 0;
  285. }
  286. }
  287. static umode_t
  288. nouveau_fan_is_visible(const void *data, u32 attr, int channel)
  289. {
  290. struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
  291. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  292. if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
  293. return 0;
  294. switch (attr) {
  295. case hwmon_fan_input:
  296. return 0444;
  297. default:
  298. return 0;
  299. }
  300. }
  301. static int
  302. nouveau_chip_read(struct device *dev, u32 attr, int channel, long *val)
  303. {
  304. switch (attr) {
  305. case hwmon_chip_update_interval:
  306. *val = 1000;
  307. break;
  308. default:
  309. return -EOPNOTSUPP;
  310. }
  311. return 0;
  312. }
  313. static int
  314. nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
  315. {
  316. struct drm_device *drm_dev = dev_get_drvdata(dev);
  317. struct nouveau_drm *drm = nouveau_drm(drm_dev);
  318. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  319. int ret;
  320. if (!therm || !therm->attr_get)
  321. return -EOPNOTSUPP;
  322. switch (attr) {
  323. case hwmon_temp_input:
  324. if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
  325. return -EINVAL;
  326. ret = nvkm_therm_temp_get(therm);
  327. *val = ret < 0 ? ret : (ret * 1000);
  328. break;
  329. case hwmon_temp_max:
  330. *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
  331. * 1000;
  332. break;
  333. case hwmon_temp_max_hyst:
  334. *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST)
  335. * 1000;
  336. break;
  337. case hwmon_temp_crit:
  338. *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL)
  339. * 1000;
  340. break;
  341. case hwmon_temp_crit_hyst:
  342. *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST)
  343. * 1000;
  344. break;
  345. case hwmon_temp_emergency:
  346. *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN)
  347. * 1000;
  348. break;
  349. case hwmon_temp_emergency_hyst:
  350. *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST)
  351. * 1000;
  352. break;
  353. default:
  354. return -EOPNOTSUPP;
  355. }
  356. return 0;
  357. }
  358. static int
  359. nouveau_fan_read(struct device *dev, u32 attr, int channel, long *val)
  360. {
  361. struct drm_device *drm_dev = dev_get_drvdata(dev);
  362. struct nouveau_drm *drm = nouveau_drm(drm_dev);
  363. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  364. if (!therm)
  365. return -EOPNOTSUPP;
  366. switch (attr) {
  367. case hwmon_fan_input:
  368. if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
  369. return -EINVAL;
  370. *val = nvkm_therm_fan_sense(therm);
  371. break;
  372. default:
  373. return -EOPNOTSUPP;
  374. }
  375. return 0;
  376. }
  377. static int
  378. nouveau_in_read(struct device *dev, u32 attr, int channel, long *val)
  379. {
  380. struct drm_device *drm_dev = dev_get_drvdata(dev);
  381. struct nouveau_drm *drm = nouveau_drm(drm_dev);
  382. struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
  383. int ret;
  384. if (!volt)
  385. return -EOPNOTSUPP;
  386. switch (attr) {
  387. case hwmon_in_input:
  388. if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
  389. return -EINVAL;
  390. ret = nvkm_volt_get(volt);
  391. *val = ret < 0 ? ret : (ret / 1000);
  392. break;
  393. case hwmon_in_min:
  394. *val = volt->min_uv > 0 ? (volt->min_uv / 1000) : -ENODEV;
  395. break;
  396. case hwmon_in_max:
  397. *val = volt->max_uv > 0 ? (volt->max_uv / 1000) : -ENODEV;
  398. break;
  399. default:
  400. return -EOPNOTSUPP;
  401. }
  402. return 0;
  403. }
  404. static int
  405. nouveau_pwm_read(struct device *dev, u32 attr, int channel, long *val)
  406. {
  407. struct drm_device *drm_dev = dev_get_drvdata(dev);
  408. struct nouveau_drm *drm = nouveau_drm(drm_dev);
  409. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  410. if (!therm || !therm->attr_get || !therm->fan_get)
  411. return -EOPNOTSUPP;
  412. switch (attr) {
  413. case hwmon_pwm_enable:
  414. *val = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
  415. break;
  416. case hwmon_pwm_input:
  417. if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
  418. return -EINVAL;
  419. *val = therm->fan_get(therm);
  420. break;
  421. default:
  422. return -EOPNOTSUPP;
  423. }
  424. return 0;
  425. }
  426. static int
  427. nouveau_power_read(struct device *dev, u32 attr, int channel, long *val)
  428. {
  429. struct drm_device *drm_dev = dev_get_drvdata(dev);
  430. struct nouveau_drm *drm = nouveau_drm(drm_dev);
  431. struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
  432. if (!iccsense)
  433. return -EOPNOTSUPP;
  434. switch (attr) {
  435. case hwmon_power_input:
  436. if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON)
  437. return -EINVAL;
  438. *val = nvkm_iccsense_read_all(iccsense);
  439. break;
  440. case hwmon_power_max:
  441. *val = iccsense->power_w_max;
  442. break;
  443. case hwmon_power_crit:
  444. *val = iccsense->power_w_crit;
  445. break;
  446. default:
  447. return -EOPNOTSUPP;
  448. }
  449. return 0;
  450. }
  451. static int
  452. nouveau_temp_write(struct device *dev, u32 attr, int channel, long val)
  453. {
  454. struct drm_device *drm_dev = dev_get_drvdata(dev);
  455. struct nouveau_drm *drm = nouveau_drm(drm_dev);
  456. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  457. if (!therm || !therm->attr_set)
  458. return -EOPNOTSUPP;
  459. switch (attr) {
  460. case hwmon_temp_max:
  461. return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK,
  462. val / 1000);
  463. case hwmon_temp_max_hyst:
  464. return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
  465. val / 1000);
  466. case hwmon_temp_crit:
  467. return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL,
  468. val / 1000);
  469. case hwmon_temp_crit_hyst:
  470. return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST,
  471. val / 1000);
  472. case hwmon_temp_emergency:
  473. return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN,
  474. val / 1000);
  475. case hwmon_temp_emergency_hyst:
  476. return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST,
  477. val / 1000);
  478. default:
  479. return -EOPNOTSUPP;
  480. }
  481. }
  482. static int
  483. nouveau_pwm_write(struct device *dev, u32 attr, int channel, long val)
  484. {
  485. struct drm_device *drm_dev = dev_get_drvdata(dev);
  486. struct nouveau_drm *drm = nouveau_drm(drm_dev);
  487. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  488. if (!therm || !therm->attr_set)
  489. return -EOPNOTSUPP;
  490. switch (attr) {
  491. case hwmon_pwm_input:
  492. return therm->fan_set(therm, val);
  493. case hwmon_pwm_enable:
  494. return therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, val);
  495. default:
  496. return -EOPNOTSUPP;
  497. }
  498. }
  499. static umode_t
  500. nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
  501. int channel)
  502. {
  503. switch (type) {
  504. case hwmon_chip:
  505. return nouveau_chip_is_visible(data, attr, channel);
  506. case hwmon_temp:
  507. return nouveau_temp_is_visible(data, attr, channel);
  508. case hwmon_fan:
  509. return nouveau_fan_is_visible(data, attr, channel);
  510. case hwmon_in:
  511. return nouveau_input_is_visible(data, attr, channel);
  512. case hwmon_pwm:
  513. return nouveau_pwm_is_visible(data, attr, channel);
  514. case hwmon_power:
  515. return nouveau_power_is_visible(data, attr, channel);
  516. default:
  517. return 0;
  518. }
  519. }
  520. static const char input_label[] = "GPU core";
  521. static int
  522. nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  523. int channel, const char **buf)
  524. {
  525. if (type == hwmon_in && attr == hwmon_in_label) {
  526. *buf = input_label;
  527. return 0;
  528. }
  529. return -EOPNOTSUPP;
  530. }
  531. static int
  532. nouveau_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  533. int channel, long *val)
  534. {
  535. switch (type) {
  536. case hwmon_chip:
  537. return nouveau_chip_read(dev, attr, channel, val);
  538. case hwmon_temp:
  539. return nouveau_temp_read(dev, attr, channel, val);
  540. case hwmon_fan:
  541. return nouveau_fan_read(dev, attr, channel, val);
  542. case hwmon_in:
  543. return nouveau_in_read(dev, attr, channel, val);
  544. case hwmon_pwm:
  545. return nouveau_pwm_read(dev, attr, channel, val);
  546. case hwmon_power:
  547. return nouveau_power_read(dev, attr, channel, val);
  548. default:
  549. return -EOPNOTSUPP;
  550. }
  551. }
  552. static int
  553. nouveau_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  554. int channel, long val)
  555. {
  556. switch (type) {
  557. case hwmon_temp:
  558. return nouveau_temp_write(dev, attr, channel, val);
  559. case hwmon_pwm:
  560. return nouveau_pwm_write(dev, attr, channel, val);
  561. default:
  562. return -EOPNOTSUPP;
  563. }
  564. }
  565. static const struct hwmon_ops nouveau_hwmon_ops = {
  566. .is_visible = nouveau_is_visible,
  567. .read = nouveau_read,
  568. .read_string = nouveau_read_string,
  569. .write = nouveau_write,
  570. };
  571. static const struct hwmon_chip_info nouveau_chip_info = {
  572. .ops = &nouveau_hwmon_ops,
  573. .info = nouveau_info,
  574. };
  575. #endif
  576. int
  577. nouveau_hwmon_init(struct drm_device *dev)
  578. {
  579. #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
  580. struct nouveau_drm *drm = nouveau_drm(dev);
  581. struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
  582. struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
  583. struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
  584. const struct attribute_group *special_groups[N_ATTR_GROUPS];
  585. struct nouveau_hwmon *hwmon;
  586. struct device *hwmon_dev;
  587. int ret = 0;
  588. int i = 0;
  589. if (!iccsense && !therm && !volt) {
  590. NV_DEBUG(drm, "Skipping hwmon registration\n");
  591. return 0;
  592. }
  593. hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
  594. if (!hwmon)
  595. return -ENOMEM;
  596. hwmon->dev = dev;
  597. if (therm && therm->attr_get && therm->attr_set) {
  598. if (nvkm_therm_temp_get(therm) >= 0)
  599. special_groups[i++] = &temp1_auto_point_sensor_group;
  600. if (therm->fan_get && therm->fan_get(therm) >= 0)
  601. special_groups[i++] = &pwm_fan_sensor_group;
  602. }
  603. special_groups[i] = NULL;
  604. hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
  605. &nouveau_chip_info,
  606. special_groups);
  607. if (IS_ERR(hwmon_dev)) {
  608. ret = PTR_ERR(hwmon_dev);
  609. NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
  610. return ret;
  611. }
  612. hwmon->hwmon = hwmon_dev;
  613. return 0;
  614. #else
  615. return 0;
  616. #endif
  617. }
  618. void
  619. nouveau_hwmon_fini(struct drm_device *dev)
  620. {
  621. #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
  622. struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
  623. if (!hwmon)
  624. return;
  625. if (hwmon->hwmon)
  626. hwmon_device_unregister(hwmon->hwmon);
  627. nouveau_drm(dev)->hwmon = NULL;
  628. kfree(hwmon);
  629. #endif
  630. }