thermal_sysfs.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * thermal.c - sysfs interface of thermal devices
  4. *
  5. * Copyright (C) 2016 Eduardo Valentin <edubezval@gmail.com>
  6. *
  7. * Highly based on original thermal_core.c
  8. * Copyright (C) 2008 Intel Corp
  9. * Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
  10. * Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
  11. */
  12. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13. #include <linux/container_of.h>
  14. #include <linux/sysfs.h>
  15. #include <linux/device.h>
  16. #include <linux/err.h>
  17. #include <linux/slab.h>
  18. #include <linux/string.h>
  19. #include <linux/jiffies.h>
  20. #include "thermal_core.h"
  21. /* sys I/F for thermal zone */
  22. static ssize_t
  23. type_show(struct device *dev, struct device_attribute *attr, char *buf)
  24. {
  25. struct thermal_zone_device *tz = to_thermal_zone(dev);
  26. return sprintf(buf, "%s\n", tz->type);
  27. }
  28. static ssize_t
  29. temp_show(struct device *dev, struct device_attribute *attr, char *buf)
  30. {
  31. struct thermal_zone_device *tz = to_thermal_zone(dev);
  32. int temperature, ret;
  33. ret = thermal_zone_get_temp(tz, &temperature);
  34. if (!ret)
  35. return sprintf(buf, "%d\n", temperature);
  36. if (ret == -EAGAIN)
  37. return -ENODATA;
  38. return ret;
  39. }
  40. static ssize_t
  41. mode_show(struct device *dev, struct device_attribute *attr, char *buf)
  42. {
  43. struct thermal_zone_device *tz = to_thermal_zone(dev);
  44. int enabled;
  45. mutex_lock(&tz->lock);
  46. enabled = tz->mode == THERMAL_DEVICE_ENABLED;
  47. mutex_unlock(&tz->lock);
  48. return sprintf(buf, "%s\n", enabled ? "enabled" : "disabled");
  49. }
  50. static ssize_t
  51. mode_store(struct device *dev, struct device_attribute *attr,
  52. const char *buf, size_t count)
  53. {
  54. struct thermal_zone_device *tz = to_thermal_zone(dev);
  55. int result;
  56. if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
  57. result = thermal_zone_device_enable(tz);
  58. else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
  59. result = thermal_zone_device_disable(tz);
  60. else
  61. result = -EINVAL;
  62. if (result)
  63. return result;
  64. return count;
  65. }
  66. #define thermal_trip_of_attr(_ptr_, _attr_) \
  67. ({ \
  68. struct thermal_trip_desc *td; \
  69. \
  70. td = container_of(_ptr_, struct thermal_trip_desc, \
  71. trip_attrs._attr_.attr); \
  72. &td->trip; \
  73. })
  74. static ssize_t
  75. trip_point_type_show(struct device *dev, struct device_attribute *attr,
  76. char *buf)
  77. {
  78. struct thermal_trip *trip = thermal_trip_of_attr(attr, type);
  79. return sprintf(buf, "%s\n", thermal_trip_type_name(trip->type));
  80. }
  81. static ssize_t
  82. trip_point_temp_store(struct device *dev, struct device_attribute *attr,
  83. const char *buf, size_t count)
  84. {
  85. struct thermal_trip *trip = thermal_trip_of_attr(attr, temp);
  86. struct thermal_zone_device *tz = to_thermal_zone(dev);
  87. int ret, temp;
  88. ret = kstrtoint(buf, 10, &temp);
  89. if (ret)
  90. return -EINVAL;
  91. mutex_lock(&tz->lock);
  92. if (temp == trip->temperature)
  93. goto unlock;
  94. /* Arrange the condition to avoid integer overflows. */
  95. if (temp != THERMAL_TEMP_INVALID &&
  96. temp <= trip->hysteresis + THERMAL_TEMP_INVALID) {
  97. ret = -EINVAL;
  98. goto unlock;
  99. }
  100. if (tz->ops.set_trip_temp) {
  101. ret = tz->ops.set_trip_temp(tz, trip, temp);
  102. if (ret)
  103. goto unlock;
  104. }
  105. thermal_zone_set_trip_temp(tz, trip, temp);
  106. __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
  107. unlock:
  108. mutex_unlock(&tz->lock);
  109. return ret ? ret : count;
  110. }
  111. static ssize_t
  112. trip_point_temp_show(struct device *dev, struct device_attribute *attr,
  113. char *buf)
  114. {
  115. struct thermal_trip *trip = thermal_trip_of_attr(attr, temp);
  116. return sprintf(buf, "%d\n", READ_ONCE(trip->temperature));
  117. }
  118. static ssize_t
  119. trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
  120. const char *buf, size_t count)
  121. {
  122. struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst);
  123. struct thermal_zone_device *tz = to_thermal_zone(dev);
  124. int ret, hyst;
  125. ret = kstrtoint(buf, 10, &hyst);
  126. if (ret || hyst < 0)
  127. return -EINVAL;
  128. mutex_lock(&tz->lock);
  129. if (hyst == trip->hysteresis)
  130. goto unlock;
  131. /*
  132. * Allow the hysteresis to be updated when the temperature is invalid
  133. * to allow user space to avoid having to adjust hysteresis after a
  134. * valid temperature has been set, but in that case just change the
  135. * value and do nothing else.
  136. */
  137. if (trip->temperature == THERMAL_TEMP_INVALID) {
  138. WRITE_ONCE(trip->hysteresis, hyst);
  139. goto unlock;
  140. }
  141. if (trip->temperature - hyst <= THERMAL_TEMP_INVALID) {
  142. ret = -EINVAL;
  143. goto unlock;
  144. }
  145. thermal_zone_set_trip_hyst(tz, trip, hyst);
  146. __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
  147. unlock:
  148. mutex_unlock(&tz->lock);
  149. return ret ? ret : count;
  150. }
  151. static ssize_t
  152. trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
  153. char *buf)
  154. {
  155. struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst);
  156. return sprintf(buf, "%d\n", READ_ONCE(trip->hysteresis));
  157. }
  158. static ssize_t
  159. policy_store(struct device *dev, struct device_attribute *attr,
  160. const char *buf, size_t count)
  161. {
  162. struct thermal_zone_device *tz = to_thermal_zone(dev);
  163. char name[THERMAL_NAME_LENGTH];
  164. int ret;
  165. snprintf(name, sizeof(name), "%s", buf);
  166. ret = thermal_zone_device_set_policy(tz, name);
  167. if (!ret)
  168. ret = count;
  169. return ret;
  170. }
  171. static ssize_t
  172. policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
  173. {
  174. struct thermal_zone_device *tz = to_thermal_zone(dev);
  175. return sprintf(buf, "%s\n", tz->governor->name);
  176. }
  177. static ssize_t
  178. available_policies_show(struct device *dev, struct device_attribute *devattr,
  179. char *buf)
  180. {
  181. return thermal_build_list_of_policies(buf);
  182. }
  183. #if (IS_ENABLED(CONFIG_THERMAL_EMULATION))
  184. static ssize_t
  185. emul_temp_store(struct device *dev, struct device_attribute *attr,
  186. const char *buf, size_t count)
  187. {
  188. struct thermal_zone_device *tz = to_thermal_zone(dev);
  189. int ret = 0;
  190. int temperature;
  191. if (kstrtoint(buf, 10, &temperature))
  192. return -EINVAL;
  193. mutex_lock(&tz->lock);
  194. if (!tz->ops.set_emul_temp)
  195. tz->emul_temperature = temperature;
  196. else
  197. ret = tz->ops.set_emul_temp(tz, temperature);
  198. if (!ret)
  199. __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
  200. mutex_unlock(&tz->lock);
  201. return ret ? ret : count;
  202. }
  203. static DEVICE_ATTR_WO(emul_temp);
  204. #endif
  205. static ssize_t
  206. sustainable_power_show(struct device *dev, struct device_attribute *devattr,
  207. char *buf)
  208. {
  209. struct thermal_zone_device *tz = to_thermal_zone(dev);
  210. if (tz->tzp)
  211. return sprintf(buf, "%u\n", tz->tzp->sustainable_power);
  212. else
  213. return -EIO;
  214. }
  215. static ssize_t
  216. sustainable_power_store(struct device *dev, struct device_attribute *devattr,
  217. const char *buf, size_t count)
  218. {
  219. struct thermal_zone_device *tz = to_thermal_zone(dev);
  220. u32 sustainable_power;
  221. if (!tz->tzp)
  222. return -EIO;
  223. if (kstrtou32(buf, 10, &sustainable_power))
  224. return -EINVAL;
  225. tz->tzp->sustainable_power = sustainable_power;
  226. return count;
  227. }
  228. #define create_s32_tzp_attr(name) \
  229. static ssize_t \
  230. name##_show(struct device *dev, struct device_attribute *devattr, \
  231. char *buf) \
  232. { \
  233. struct thermal_zone_device *tz = to_thermal_zone(dev); \
  234. \
  235. if (tz->tzp) \
  236. return sprintf(buf, "%d\n", tz->tzp->name); \
  237. else \
  238. return -EIO; \
  239. } \
  240. \
  241. static ssize_t \
  242. name##_store(struct device *dev, struct device_attribute *devattr, \
  243. const char *buf, size_t count) \
  244. { \
  245. struct thermal_zone_device *tz = to_thermal_zone(dev); \
  246. s32 value; \
  247. \
  248. if (!tz->tzp) \
  249. return -EIO; \
  250. \
  251. if (kstrtos32(buf, 10, &value)) \
  252. return -EINVAL; \
  253. \
  254. tz->tzp->name = value; \
  255. \
  256. return count; \
  257. } \
  258. static DEVICE_ATTR_RW(name)
  259. create_s32_tzp_attr(k_po);
  260. create_s32_tzp_attr(k_pu);
  261. create_s32_tzp_attr(k_i);
  262. create_s32_tzp_attr(k_d);
  263. create_s32_tzp_attr(integral_cutoff);
  264. create_s32_tzp_attr(slope);
  265. create_s32_tzp_attr(offset);
  266. #undef create_s32_tzp_attr
  267. /*
  268. * These are thermal zone device attributes that will always be present.
  269. * All the attributes created for tzp (create_s32_tzp_attr) also are always
  270. * present on the sysfs interface.
  271. */
  272. static DEVICE_ATTR_RO(type);
  273. static DEVICE_ATTR_RO(temp);
  274. static DEVICE_ATTR_RW(policy);
  275. static DEVICE_ATTR_RO(available_policies);
  276. static DEVICE_ATTR_RW(sustainable_power);
  277. /* These thermal zone device attributes are created based on conditions */
  278. static DEVICE_ATTR_RW(mode);
  279. /* These attributes are unconditionally added to a thermal zone */
  280. static struct attribute *thermal_zone_dev_attrs[] = {
  281. &dev_attr_type.attr,
  282. &dev_attr_temp.attr,
  283. #if (IS_ENABLED(CONFIG_THERMAL_EMULATION))
  284. &dev_attr_emul_temp.attr,
  285. #endif
  286. &dev_attr_policy.attr,
  287. &dev_attr_available_policies.attr,
  288. &dev_attr_sustainable_power.attr,
  289. &dev_attr_k_po.attr,
  290. &dev_attr_k_pu.attr,
  291. &dev_attr_k_i.attr,
  292. &dev_attr_k_d.attr,
  293. &dev_attr_integral_cutoff.attr,
  294. &dev_attr_slope.attr,
  295. &dev_attr_offset.attr,
  296. NULL,
  297. };
  298. static const struct attribute_group thermal_zone_attribute_group = {
  299. .attrs = thermal_zone_dev_attrs,
  300. };
  301. static struct attribute *thermal_zone_mode_attrs[] = {
  302. &dev_attr_mode.attr,
  303. NULL,
  304. };
  305. static const struct attribute_group thermal_zone_mode_attribute_group = {
  306. .attrs = thermal_zone_mode_attrs,
  307. };
  308. static const struct attribute_group *thermal_zone_attribute_groups[] = {
  309. &thermal_zone_attribute_group,
  310. &thermal_zone_mode_attribute_group,
  311. /* This is not NULL terminated as we create the group dynamically */
  312. };
  313. /**
  314. * create_trip_attrs() - create attributes for trip points
  315. * @tz: the thermal zone device
  316. *
  317. * helper function to instantiate sysfs entries for every trip
  318. * point and its properties of a struct thermal_zone_device.
  319. *
  320. * Return: 0 on success, the proper error value otherwise.
  321. */
  322. static int create_trip_attrs(struct thermal_zone_device *tz)
  323. {
  324. struct thermal_trip_desc *td;
  325. struct attribute **attrs;
  326. int i;
  327. attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
  328. if (!attrs)
  329. return -ENOMEM;
  330. i = 0;
  331. for_each_trip_desc(tz, td) {
  332. struct thermal_trip_attrs *trip_attrs = &td->trip_attrs;
  333. /* create trip type attribute */
  334. snprintf(trip_attrs->type.name, THERMAL_NAME_LENGTH,
  335. "trip_point_%d_type", i);
  336. sysfs_attr_init(&trip_attrs->type.attr.attr);
  337. trip_attrs->type.attr.attr.name = trip_attrs->type.name;
  338. trip_attrs->type.attr.attr.mode = S_IRUGO;
  339. trip_attrs->type.attr.show = trip_point_type_show;
  340. attrs[i] = &trip_attrs->type.attr.attr;
  341. /* create trip temp attribute */
  342. snprintf(trip_attrs->temp.name, THERMAL_NAME_LENGTH,
  343. "trip_point_%d_temp", i);
  344. sysfs_attr_init(&trip_attrs->temp.attr.attr);
  345. trip_attrs->temp.attr.attr.name = trip_attrs->temp.name;
  346. trip_attrs->temp.attr.attr.mode = S_IRUGO;
  347. trip_attrs->temp.attr.show = trip_point_temp_show;
  348. if (td->trip.flags & THERMAL_TRIP_FLAG_RW_TEMP) {
  349. trip_attrs->temp.attr.attr.mode |= S_IWUSR;
  350. trip_attrs->temp.attr.store = trip_point_temp_store;
  351. }
  352. attrs[i + tz->num_trips] = &trip_attrs->temp.attr.attr;
  353. snprintf(trip_attrs->hyst.name, THERMAL_NAME_LENGTH,
  354. "trip_point_%d_hyst", i);
  355. sysfs_attr_init(&trip_attrs->hyst.attr.attr);
  356. trip_attrs->hyst.attr.attr.name = trip_attrs->hyst.name;
  357. trip_attrs->hyst.attr.attr.mode = S_IRUGO;
  358. trip_attrs->hyst.attr.show = trip_point_hyst_show;
  359. if (td->trip.flags & THERMAL_TRIP_FLAG_RW_HYST) {
  360. trip_attrs->hyst.attr.attr.mode |= S_IWUSR;
  361. trip_attrs->hyst.attr.store = trip_point_hyst_store;
  362. }
  363. attrs[i + 2 * tz->num_trips] = &trip_attrs->hyst.attr.attr;
  364. i++;
  365. }
  366. attrs[tz->num_trips * 3] = NULL;
  367. tz->trips_attribute_group.attrs = attrs;
  368. return 0;
  369. }
  370. /**
  371. * destroy_trip_attrs() - destroy attributes for trip points
  372. * @tz: the thermal zone device
  373. *
  374. * helper function to free resources allocated by create_trip_attrs()
  375. */
  376. static void destroy_trip_attrs(struct thermal_zone_device *tz)
  377. {
  378. if (tz)
  379. kfree(tz->trips_attribute_group.attrs);
  380. }
  381. int thermal_zone_create_device_groups(struct thermal_zone_device *tz)
  382. {
  383. const struct attribute_group **groups;
  384. int i, size, result;
  385. /* we need one extra for trips and the NULL to terminate the array */
  386. size = ARRAY_SIZE(thermal_zone_attribute_groups) + 2;
  387. /* This also takes care of API requirement to be NULL terminated */
  388. groups = kcalloc(size, sizeof(*groups), GFP_KERNEL);
  389. if (!groups)
  390. return -ENOMEM;
  391. for (i = 0; i < size - 2; i++)
  392. groups[i] = thermal_zone_attribute_groups[i];
  393. if (tz->num_trips) {
  394. result = create_trip_attrs(tz);
  395. if (result) {
  396. kfree(groups);
  397. return result;
  398. }
  399. groups[size - 2] = &tz->trips_attribute_group;
  400. }
  401. tz->device.groups = groups;
  402. return 0;
  403. }
  404. void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz)
  405. {
  406. if (!tz)
  407. return;
  408. if (tz->num_trips)
  409. destroy_trip_attrs(tz);
  410. kfree(tz->device.groups);
  411. }
  412. /* sys I/F for cooling device */
  413. static ssize_t
  414. cdev_type_show(struct device *dev, struct device_attribute *attr, char *buf)
  415. {
  416. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  417. return sprintf(buf, "%s\n", cdev->type);
  418. }
  419. static ssize_t max_state_show(struct device *dev, struct device_attribute *attr,
  420. char *buf)
  421. {
  422. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  423. return sprintf(buf, "%ld\n", cdev->max_state);
  424. }
  425. static ssize_t cur_state_show(struct device *dev, struct device_attribute *attr,
  426. char *buf)
  427. {
  428. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  429. unsigned long state;
  430. int ret;
  431. ret = cdev->ops->get_cur_state(cdev, &state);
  432. if (ret)
  433. return ret;
  434. return sprintf(buf, "%ld\n", state);
  435. }
  436. static ssize_t
  437. cur_state_store(struct device *dev, struct device_attribute *attr,
  438. const char *buf, size_t count)
  439. {
  440. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  441. unsigned long state;
  442. int result;
  443. if (sscanf(buf, "%ld\n", &state) != 1)
  444. return -EINVAL;
  445. if ((long)state < 0)
  446. return -EINVAL;
  447. /* Requested state should be less than max_state + 1 */
  448. if (state > cdev->max_state)
  449. return -EINVAL;
  450. mutex_lock(&cdev->lock);
  451. result = cdev->ops->set_cur_state(cdev, state);
  452. if (!result)
  453. thermal_cooling_device_stats_update(cdev, state);
  454. mutex_unlock(&cdev->lock);
  455. return result ? result : count;
  456. }
  457. static struct device_attribute
  458. dev_attr_cdev_type = __ATTR(type, 0444, cdev_type_show, NULL);
  459. static DEVICE_ATTR_RO(max_state);
  460. static DEVICE_ATTR_RW(cur_state);
  461. static struct attribute *cooling_device_attrs[] = {
  462. &dev_attr_cdev_type.attr,
  463. &dev_attr_max_state.attr,
  464. &dev_attr_cur_state.attr,
  465. NULL,
  466. };
  467. static const struct attribute_group cooling_device_attr_group = {
  468. .attrs = cooling_device_attrs,
  469. };
  470. static const struct attribute_group *cooling_device_attr_groups[] = {
  471. &cooling_device_attr_group,
  472. NULL, /* Space allocated for cooling_device_stats_attr_group */
  473. NULL,
  474. };
  475. #ifdef CONFIG_THERMAL_STATISTICS
  476. struct cooling_dev_stats {
  477. spinlock_t lock;
  478. unsigned int total_trans;
  479. unsigned long state;
  480. ktime_t last_time;
  481. ktime_t *time_in_state;
  482. unsigned int *trans_table;
  483. };
  484. static void update_time_in_state(struct cooling_dev_stats *stats)
  485. {
  486. ktime_t now = ktime_get(), delta;
  487. delta = ktime_sub(now, stats->last_time);
  488. stats->time_in_state[stats->state] =
  489. ktime_add(stats->time_in_state[stats->state], delta);
  490. stats->last_time = now;
  491. }
  492. void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
  493. unsigned long new_state)
  494. {
  495. struct cooling_dev_stats *stats = cdev->stats;
  496. lockdep_assert_held(&cdev->lock);
  497. if (!stats)
  498. return;
  499. spin_lock(&stats->lock);
  500. if (stats->state == new_state)
  501. goto unlock;
  502. update_time_in_state(stats);
  503. stats->trans_table[stats->state * (cdev->max_state + 1) + new_state]++;
  504. stats->state = new_state;
  505. stats->total_trans++;
  506. unlock:
  507. spin_unlock(&stats->lock);
  508. }
  509. static ssize_t total_trans_show(struct device *dev,
  510. struct device_attribute *attr, char *buf)
  511. {
  512. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  513. struct cooling_dev_stats *stats;
  514. int ret = 0;
  515. mutex_lock(&cdev->lock);
  516. stats = cdev->stats;
  517. if (!stats)
  518. goto unlock;
  519. spin_lock(&stats->lock);
  520. ret = sprintf(buf, "%u\n", stats->total_trans);
  521. spin_unlock(&stats->lock);
  522. unlock:
  523. mutex_unlock(&cdev->lock);
  524. return ret;
  525. }
  526. static ssize_t
  527. time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
  528. char *buf)
  529. {
  530. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  531. struct cooling_dev_stats *stats;
  532. ssize_t len = 0;
  533. int i;
  534. mutex_lock(&cdev->lock);
  535. stats = cdev->stats;
  536. if (!stats)
  537. goto unlock;
  538. spin_lock(&stats->lock);
  539. update_time_in_state(stats);
  540. for (i = 0; i <= cdev->max_state; i++) {
  541. len += sprintf(buf + len, "state%u\t%llu\n", i,
  542. ktime_to_ms(stats->time_in_state[i]));
  543. }
  544. spin_unlock(&stats->lock);
  545. unlock:
  546. mutex_unlock(&cdev->lock);
  547. return len;
  548. }
  549. static ssize_t
  550. reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
  551. size_t count)
  552. {
  553. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  554. struct cooling_dev_stats *stats;
  555. int i, states;
  556. mutex_lock(&cdev->lock);
  557. stats = cdev->stats;
  558. if (!stats)
  559. goto unlock;
  560. states = cdev->max_state + 1;
  561. spin_lock(&stats->lock);
  562. stats->total_trans = 0;
  563. stats->last_time = ktime_get();
  564. memset(stats->trans_table, 0,
  565. states * states * sizeof(*stats->trans_table));
  566. for (i = 0; i < states; i++)
  567. stats->time_in_state[i] = ktime_set(0, 0);
  568. spin_unlock(&stats->lock);
  569. unlock:
  570. mutex_unlock(&cdev->lock);
  571. return count;
  572. }
  573. static ssize_t trans_table_show(struct device *dev,
  574. struct device_attribute *attr, char *buf)
  575. {
  576. struct thermal_cooling_device *cdev = to_cooling_device(dev);
  577. struct cooling_dev_stats *stats;
  578. ssize_t len = 0;
  579. int i, j;
  580. mutex_lock(&cdev->lock);
  581. stats = cdev->stats;
  582. if (!stats) {
  583. len = -ENODATA;
  584. goto unlock;
  585. }
  586. len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n");
  587. len += snprintf(buf + len, PAGE_SIZE - len, " : ");
  588. for (i = 0; i <= cdev->max_state; i++) {
  589. if (len >= PAGE_SIZE)
  590. break;
  591. len += snprintf(buf + len, PAGE_SIZE - len, "state%2u ", i);
  592. }
  593. if (len >= PAGE_SIZE) {
  594. len = PAGE_SIZE;
  595. goto unlock;
  596. }
  597. len += snprintf(buf + len, PAGE_SIZE - len, "\n");
  598. for (i = 0; i <= cdev->max_state; i++) {
  599. if (len >= PAGE_SIZE)
  600. break;
  601. len += snprintf(buf + len, PAGE_SIZE - len, "state%2u:", i);
  602. for (j = 0; j <= cdev->max_state; j++) {
  603. if (len >= PAGE_SIZE)
  604. break;
  605. len += snprintf(buf + len, PAGE_SIZE - len, "%8u ",
  606. stats->trans_table[i * (cdev->max_state + 1) + j]);
  607. }
  608. if (len >= PAGE_SIZE)
  609. break;
  610. len += snprintf(buf + len, PAGE_SIZE - len, "\n");
  611. }
  612. if (len >= PAGE_SIZE) {
  613. pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n");
  614. len = -EFBIG;
  615. }
  616. unlock:
  617. mutex_unlock(&cdev->lock);
  618. return len;
  619. }
  620. static DEVICE_ATTR_RO(total_trans);
  621. static DEVICE_ATTR_RO(time_in_state_ms);
  622. static DEVICE_ATTR_WO(reset);
  623. static DEVICE_ATTR_RO(trans_table);
  624. static struct attribute *cooling_device_stats_attrs[] = {
  625. &dev_attr_total_trans.attr,
  626. &dev_attr_time_in_state_ms.attr,
  627. &dev_attr_reset.attr,
  628. &dev_attr_trans_table.attr,
  629. NULL
  630. };
  631. static const struct attribute_group cooling_device_stats_attr_group = {
  632. .attrs = cooling_device_stats_attrs,
  633. .name = "stats"
  634. };
  635. static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
  636. {
  637. const struct attribute_group *stats_attr_group = NULL;
  638. struct cooling_dev_stats *stats;
  639. /* Total number of states is highest state + 1 */
  640. unsigned long states = cdev->max_state + 1;
  641. int var;
  642. var = sizeof(*stats);
  643. var += sizeof(*stats->time_in_state) * states;
  644. var += sizeof(*stats->trans_table) * states * states;
  645. stats = kzalloc(var, GFP_KERNEL);
  646. if (!stats)
  647. goto out;
  648. stats->time_in_state = (ktime_t *)(stats + 1);
  649. stats->trans_table = (unsigned int *)(stats->time_in_state + states);
  650. cdev->stats = stats;
  651. stats->last_time = ktime_get();
  652. spin_lock_init(&stats->lock);
  653. stats_attr_group = &cooling_device_stats_attr_group;
  654. out:
  655. /* Fill the empty slot left in cooling_device_attr_groups */
  656. var = ARRAY_SIZE(cooling_device_attr_groups) - 2;
  657. cooling_device_attr_groups[var] = stats_attr_group;
  658. }
  659. static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
  660. {
  661. kfree(cdev->stats);
  662. cdev->stats = NULL;
  663. }
  664. #else
  665. static inline void
  666. cooling_device_stats_setup(struct thermal_cooling_device *cdev) {}
  667. static inline void
  668. cooling_device_stats_destroy(struct thermal_cooling_device *cdev) {}
  669. #endif /* CONFIG_THERMAL_STATISTICS */
  670. void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *cdev)
  671. {
  672. cooling_device_stats_setup(cdev);
  673. cdev->device.groups = cooling_device_attr_groups;
  674. }
  675. void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev)
  676. {
  677. cooling_device_stats_destroy(cdev);
  678. }
  679. void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev)
  680. {
  681. lockdep_assert_held(&cdev->lock);
  682. cooling_device_stats_destroy(cdev);
  683. cooling_device_stats_setup(cdev);
  684. }
  685. /* these helper will be used only at the time of bindig */
  686. ssize_t
  687. trip_point_show(struct device *dev, struct device_attribute *attr, char *buf)
  688. {
  689. struct thermal_zone_device *tz = to_thermal_zone(dev);
  690. struct thermal_instance *instance;
  691. instance = container_of(attr, struct thermal_instance, attr);
  692. return sprintf(buf, "%d\n", thermal_zone_trip_id(tz, instance->trip));
  693. }
  694. ssize_t
  695. weight_show(struct device *dev, struct device_attribute *attr, char *buf)
  696. {
  697. struct thermal_instance *instance;
  698. instance = container_of(attr, struct thermal_instance, weight_attr);
  699. return sprintf(buf, "%d\n", instance->weight);
  700. }
  701. ssize_t weight_store(struct device *dev, struct device_attribute *attr,
  702. const char *buf, size_t count)
  703. {
  704. struct thermal_zone_device *tz = to_thermal_zone(dev);
  705. struct thermal_instance *instance;
  706. int ret, weight;
  707. ret = kstrtoint(buf, 0, &weight);
  708. if (ret)
  709. return ret;
  710. instance = container_of(attr, struct thermal_instance, weight_attr);
  711. /* Don't race with governors using the 'weight' value */
  712. mutex_lock(&tz->lock);
  713. instance->weight = weight;
  714. thermal_governor_update_tz(tz, THERMAL_INSTANCE_WEIGHT_CHANGED);
  715. mutex_unlock(&tz->lock);
  716. return count;
  717. }