thermal.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // SPDX-License-Identifier: ISC
  2. /*
  3. * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
  4. */
  5. #include <linux/device.h>
  6. #include <linux/sysfs.h>
  7. #include <linux/thermal.h>
  8. #include <linux/hwmon.h>
  9. #include <linux/hwmon-sysfs.h>
  10. #include "core.h"
  11. #include "debug.h"
  12. #include "wmi-ops.h"
  13. static int
  14. ath10k_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
  15. unsigned long *state)
  16. {
  17. *state = ATH10K_THERMAL_THROTTLE_MAX;
  18. return 0;
  19. }
  20. static int
  21. ath10k_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,
  22. unsigned long *state)
  23. {
  24. struct ath10k *ar = cdev->devdata;
  25. mutex_lock(&ar->conf_mutex);
  26. *state = ar->thermal.throttle_state;
  27. mutex_unlock(&ar->conf_mutex);
  28. return 0;
  29. }
  30. static int
  31. ath10k_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
  32. unsigned long throttle_state)
  33. {
  34. struct ath10k *ar = cdev->devdata;
  35. if (throttle_state > ATH10K_THERMAL_THROTTLE_MAX) {
  36. ath10k_warn(ar, "throttle state %ld is exceeding the limit %d\n",
  37. throttle_state, ATH10K_THERMAL_THROTTLE_MAX);
  38. return -EINVAL;
  39. }
  40. mutex_lock(&ar->conf_mutex);
  41. ar->thermal.throttle_state = throttle_state;
  42. ath10k_thermal_set_throttling(ar);
  43. mutex_unlock(&ar->conf_mutex);
  44. return 0;
  45. }
  46. static const struct thermal_cooling_device_ops ath10k_thermal_ops = {
  47. .get_max_state = ath10k_thermal_get_max_throttle_state,
  48. .get_cur_state = ath10k_thermal_get_cur_throttle_state,
  49. .set_cur_state = ath10k_thermal_set_cur_throttle_state,
  50. };
  51. static ssize_t ath10k_thermal_show_temp(struct device *dev,
  52. struct device_attribute *attr,
  53. char *buf)
  54. {
  55. struct ath10k *ar = dev_get_drvdata(dev);
  56. int ret, temperature;
  57. unsigned long time_left;
  58. mutex_lock(&ar->conf_mutex);
  59. /* Can't get temperature when the card is off */
  60. if (ar->state != ATH10K_STATE_ON) {
  61. ret = -ENETDOWN;
  62. goto out;
  63. }
  64. reinit_completion(&ar->thermal.wmi_sync);
  65. ret = ath10k_wmi_pdev_get_temperature(ar);
  66. if (ret) {
  67. ath10k_warn(ar, "failed to read temperature %d\n", ret);
  68. goto out;
  69. }
  70. if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
  71. ret = -ESHUTDOWN;
  72. goto out;
  73. }
  74. time_left = wait_for_completion_timeout(&ar->thermal.wmi_sync,
  75. ATH10K_THERMAL_SYNC_TIMEOUT_HZ);
  76. if (!time_left) {
  77. ath10k_warn(ar, "failed to synchronize thermal read\n");
  78. ret = -ETIMEDOUT;
  79. goto out;
  80. }
  81. spin_lock_bh(&ar->data_lock);
  82. temperature = ar->thermal.temperature;
  83. spin_unlock_bh(&ar->data_lock);
  84. /* display in millidegree celsius */
  85. ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000);
  86. out:
  87. mutex_unlock(&ar->conf_mutex);
  88. return ret;
  89. }
  90. void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature)
  91. {
  92. spin_lock_bh(&ar->data_lock);
  93. ar->thermal.temperature = temperature;
  94. spin_unlock_bh(&ar->data_lock);
  95. complete(&ar->thermal.wmi_sync);
  96. }
  97. static SENSOR_DEVICE_ATTR(temp1_input, 0444, ath10k_thermal_show_temp,
  98. NULL, 0);
  99. static struct attribute *ath10k_hwmon_attrs[] = {
  100. &sensor_dev_attr_temp1_input.dev_attr.attr,
  101. NULL,
  102. };
  103. ATTRIBUTE_GROUPS(ath10k_hwmon);
  104. void ath10k_thermal_set_throttling(struct ath10k *ar)
  105. {
  106. u32 period, duration, enabled;
  107. int ret;
  108. lockdep_assert_held(&ar->conf_mutex);
  109. if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
  110. return;
  111. if (!ar->wmi.ops->gen_pdev_set_quiet_mode)
  112. return;
  113. if (ar->state != ATH10K_STATE_ON)
  114. return;
  115. period = ar->thermal.quiet_period;
  116. duration = (period * ar->thermal.throttle_state) / 100;
  117. enabled = duration ? 1 : 0;
  118. ret = ath10k_wmi_pdev_set_quiet_mode(ar, period, duration,
  119. ATH10K_QUIET_START_OFFSET,
  120. enabled);
  121. if (ret) {
  122. ath10k_warn(ar, "failed to set quiet mode period %u duarion %u enabled %u ret %d\n",
  123. period, duration, enabled, ret);
  124. }
  125. }
  126. int ath10k_thermal_register(struct ath10k *ar)
  127. {
  128. struct thermal_cooling_device *cdev;
  129. struct device *hwmon_dev;
  130. int ret;
  131. if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
  132. return 0;
  133. cdev = thermal_cooling_device_register("ath10k_thermal", ar,
  134. &ath10k_thermal_ops);
  135. if (IS_ERR(cdev)) {
  136. ath10k_err(ar, "failed to setup thermal device result: %ld\n",
  137. PTR_ERR(cdev));
  138. return -EINVAL;
  139. }
  140. ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj,
  141. "cooling_device");
  142. if (ret) {
  143. ath10k_err(ar, "failed to create cooling device symlink\n");
  144. goto err_cooling_destroy;
  145. }
  146. ar->thermal.cdev = cdev;
  147. ar->thermal.quiet_period = ATH10K_QUIET_PERIOD_DEFAULT;
  148. /* Do not register hwmon device when temperature reading is not
  149. * supported by firmware
  150. */
  151. if (!(ar->wmi.ops->gen_pdev_get_temperature))
  152. return 0;
  153. /* Avoid linking error on devm_hwmon_device_register_with_groups, I
  154. * guess linux/hwmon.h is missing proper stubs.
  155. */
  156. if (!IS_REACHABLE(CONFIG_HWMON))
  157. return 0;
  158. hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev,
  159. "ath10k_hwmon", ar,
  160. ath10k_hwmon_groups);
  161. if (IS_ERR(hwmon_dev)) {
  162. ath10k_err(ar, "failed to register hwmon device: %ld\n",
  163. PTR_ERR(hwmon_dev));
  164. ret = -EINVAL;
  165. goto err_remove_link;
  166. }
  167. return 0;
  168. err_remove_link:
  169. sysfs_remove_link(&ar->dev->kobj, "cooling_device");
  170. err_cooling_destroy:
  171. thermal_cooling_device_unregister(cdev);
  172. return ret;
  173. }
  174. void ath10k_thermal_unregister(struct ath10k *ar)
  175. {
  176. if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
  177. return;
  178. sysfs_remove_link(&ar->dev->kobj, "cooling_device");
  179. thermal_cooling_device_unregister(ar->thermal.cdev);
  180. }