nouveau_hwmon.c 19 KB

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