0001
0002
0003
0004
0005
0006 #include <linux/device.h>
0007 #include <linux/sysfs.h>
0008 #include <linux/thermal.h>
0009 #include <linux/hwmon.h>
0010 #include <linux/hwmon-sysfs.h>
0011 #include "core.h"
0012 #include "debug.h"
0013
0014 static int
0015 ath11k_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
0016 unsigned long *state)
0017 {
0018 *state = ATH11K_THERMAL_THROTTLE_MAX;
0019
0020 return 0;
0021 }
0022
0023 static int
0024 ath11k_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,
0025 unsigned long *state)
0026 {
0027 struct ath11k *ar = cdev->devdata;
0028
0029 mutex_lock(&ar->conf_mutex);
0030 *state = ar->thermal.throttle_state;
0031 mutex_unlock(&ar->conf_mutex);
0032
0033 return 0;
0034 }
0035
0036 static int
0037 ath11k_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
0038 unsigned long throttle_state)
0039 {
0040 struct ath11k *ar = cdev->devdata;
0041 int ret;
0042
0043 if (throttle_state > ATH11K_THERMAL_THROTTLE_MAX) {
0044 ath11k_warn(ar->ab, "throttle state %ld is exceeding the limit %d\n",
0045 throttle_state, ATH11K_THERMAL_THROTTLE_MAX);
0046 return -EINVAL;
0047 }
0048 mutex_lock(&ar->conf_mutex);
0049 ret = ath11k_thermal_set_throttling(ar, throttle_state);
0050 if (ret == 0)
0051 ar->thermal.throttle_state = throttle_state;
0052 mutex_unlock(&ar->conf_mutex);
0053 return ret;
0054 }
0055
0056 static const struct thermal_cooling_device_ops ath11k_thermal_ops = {
0057 .get_max_state = ath11k_thermal_get_max_throttle_state,
0058 .get_cur_state = ath11k_thermal_get_cur_throttle_state,
0059 .set_cur_state = ath11k_thermal_set_cur_throttle_state,
0060 };
0061
0062 static ssize_t ath11k_thermal_show_temp(struct device *dev,
0063 struct device_attribute *attr,
0064 char *buf)
0065 {
0066 struct ath11k *ar = dev_get_drvdata(dev);
0067 int ret, temperature;
0068 unsigned long time_left;
0069
0070 mutex_lock(&ar->conf_mutex);
0071
0072
0073 if (ar->state != ATH11K_STATE_ON) {
0074 ret = -ENETDOWN;
0075 goto out;
0076 }
0077
0078 reinit_completion(&ar->thermal.wmi_sync);
0079 ret = ath11k_wmi_send_pdev_temperature_cmd(ar);
0080 if (ret) {
0081 ath11k_warn(ar->ab, "failed to read temperature %d\n", ret);
0082 goto out;
0083 }
0084
0085 if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) {
0086 ret = -ESHUTDOWN;
0087 goto out;
0088 }
0089
0090 time_left = wait_for_completion_timeout(&ar->thermal.wmi_sync,
0091 ATH11K_THERMAL_SYNC_TIMEOUT_HZ);
0092 if (!time_left) {
0093 ath11k_warn(ar->ab, "failed to synchronize thermal read\n");
0094 ret = -ETIMEDOUT;
0095 goto out;
0096 }
0097
0098 spin_lock_bh(&ar->data_lock);
0099 temperature = ar->thermal.temperature;
0100 spin_unlock_bh(&ar->data_lock);
0101
0102
0103 ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000);
0104 out:
0105 mutex_unlock(&ar->conf_mutex);
0106 return ret;
0107 }
0108
0109 void ath11k_thermal_event_temperature(struct ath11k *ar, int temperature)
0110 {
0111 spin_lock_bh(&ar->data_lock);
0112 ar->thermal.temperature = temperature;
0113 spin_unlock_bh(&ar->data_lock);
0114 complete(&ar->thermal.wmi_sync);
0115 }
0116
0117 static SENSOR_DEVICE_ATTR(temp1_input, 0444, ath11k_thermal_show_temp,
0118 NULL, 0);
0119
0120 static struct attribute *ath11k_hwmon_attrs[] = {
0121 &sensor_dev_attr_temp1_input.dev_attr.attr,
0122 NULL,
0123 };
0124 ATTRIBUTE_GROUPS(ath11k_hwmon);
0125
0126 int ath11k_thermal_set_throttling(struct ath11k *ar, u32 throttle_state)
0127 {
0128 struct ath11k_base *sc = ar->ab;
0129 struct thermal_mitigation_params param;
0130 int ret = 0;
0131
0132 lockdep_assert_held(&ar->conf_mutex);
0133
0134 if (ar->state != ATH11K_STATE_ON)
0135 return 0;
0136
0137 memset(¶m, 0, sizeof(param));
0138 param.pdev_id = ar->pdev->pdev_id;
0139 param.enable = throttle_state ? 1 : 0;
0140 param.dc = ATH11K_THERMAL_DEFAULT_DUTY_CYCLE;
0141 param.dc_per_event = 0xFFFFFFFF;
0142
0143 param.levelconf[0].tmplwm = ATH11K_THERMAL_TEMP_LOW_MARK;
0144 param.levelconf[0].tmphwm = ATH11K_THERMAL_TEMP_HIGH_MARK;
0145 param.levelconf[0].dcoffpercent = throttle_state;
0146 param.levelconf[0].priority = 0;
0147
0148 ret = ath11k_wmi_send_thermal_mitigation_param_cmd(ar, ¶m);
0149 if (ret) {
0150 ath11k_warn(sc, "failed to send thermal mitigation duty cycle %u ret %d\n",
0151 throttle_state, ret);
0152 }
0153
0154 return ret;
0155 }
0156
0157 int ath11k_thermal_register(struct ath11k_base *sc)
0158 {
0159 struct thermal_cooling_device *cdev;
0160 struct device *hwmon_dev;
0161 struct ath11k *ar;
0162 struct ath11k_pdev *pdev;
0163 int i, ret;
0164
0165 for (i = 0; i < sc->num_radios; i++) {
0166 pdev = &sc->pdevs[i];
0167 ar = pdev->ar;
0168 if (!ar)
0169 continue;
0170
0171 cdev = thermal_cooling_device_register("ath11k_thermal", ar,
0172 &ath11k_thermal_ops);
0173
0174 if (IS_ERR(cdev)) {
0175 ath11k_err(sc, "failed to setup thermal device result: %ld\n",
0176 PTR_ERR(cdev));
0177 ret = -EINVAL;
0178 goto err_thermal_destroy;
0179 }
0180
0181 ar->thermal.cdev = cdev;
0182
0183 ret = sysfs_create_link(&ar->hw->wiphy->dev.kobj, &cdev->device.kobj,
0184 "cooling_device");
0185 if (ret) {
0186 ath11k_err(sc, "failed to create cooling device symlink\n");
0187 goto err_thermal_destroy;
0188 }
0189
0190 if (!IS_REACHABLE(CONFIG_HWMON))
0191 return 0;
0192
0193 hwmon_dev = devm_hwmon_device_register_with_groups(&ar->hw->wiphy->dev,
0194 "ath11k_hwmon", ar,
0195 ath11k_hwmon_groups);
0196 if (IS_ERR(hwmon_dev)) {
0197 ath11k_err(ar->ab, "failed to register hwmon device: %ld\n",
0198 PTR_ERR(hwmon_dev));
0199 ret = -EINVAL;
0200 goto err_thermal_destroy;
0201 }
0202 }
0203
0204 return 0;
0205
0206 err_thermal_destroy:
0207 ath11k_thermal_unregister(sc);
0208 return ret;
0209 }
0210
0211 void ath11k_thermal_unregister(struct ath11k_base *sc)
0212 {
0213 struct ath11k *ar;
0214 struct ath11k_pdev *pdev;
0215 int i;
0216
0217 for (i = 0; i < sc->num_radios; i++) {
0218 pdev = &sc->pdevs[i];
0219 ar = pdev->ar;
0220 if (!ar)
0221 continue;
0222
0223 sysfs_remove_link(&ar->hw->wiphy->dev.kobj, "cooling_device");
0224 thermal_cooling_device_unregister(ar->thermal.cdev);
0225 }
0226 }