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 #include "wmi-ops.h"
0014
0015 static int
0016 ath10k_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
0017 unsigned long *state)
0018 {
0019 *state = ATH10K_THERMAL_THROTTLE_MAX;
0020
0021 return 0;
0022 }
0023
0024 static int
0025 ath10k_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,
0026 unsigned long *state)
0027 {
0028 struct ath10k *ar = cdev->devdata;
0029
0030 mutex_lock(&ar->conf_mutex);
0031 *state = ar->thermal.throttle_state;
0032 mutex_unlock(&ar->conf_mutex);
0033
0034 return 0;
0035 }
0036
0037 static int
0038 ath10k_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
0039 unsigned long throttle_state)
0040 {
0041 struct ath10k *ar = cdev->devdata;
0042
0043 if (throttle_state > ATH10K_THERMAL_THROTTLE_MAX) {
0044 ath10k_warn(ar, "throttle state %ld is exceeding the limit %d\n",
0045 throttle_state, ATH10K_THERMAL_THROTTLE_MAX);
0046 return -EINVAL;
0047 }
0048 mutex_lock(&ar->conf_mutex);
0049 ar->thermal.throttle_state = throttle_state;
0050 ath10k_thermal_set_throttling(ar);
0051 mutex_unlock(&ar->conf_mutex);
0052 return 0;
0053 }
0054
0055 static const struct thermal_cooling_device_ops ath10k_thermal_ops = {
0056 .get_max_state = ath10k_thermal_get_max_throttle_state,
0057 .get_cur_state = ath10k_thermal_get_cur_throttle_state,
0058 .set_cur_state = ath10k_thermal_set_cur_throttle_state,
0059 };
0060
0061 static ssize_t ath10k_thermal_show_temp(struct device *dev,
0062 struct device_attribute *attr,
0063 char *buf)
0064 {
0065 struct ath10k *ar = dev_get_drvdata(dev);
0066 int ret, temperature;
0067 unsigned long time_left;
0068
0069 mutex_lock(&ar->conf_mutex);
0070
0071
0072 if (ar->state != ATH10K_STATE_ON) {
0073 ret = -ENETDOWN;
0074 goto out;
0075 }
0076
0077 reinit_completion(&ar->thermal.wmi_sync);
0078 ret = ath10k_wmi_pdev_get_temperature(ar);
0079 if (ret) {
0080 ath10k_warn(ar, "failed to read temperature %d\n", ret);
0081 goto out;
0082 }
0083
0084 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
0085 ret = -ESHUTDOWN;
0086 goto out;
0087 }
0088
0089 time_left = wait_for_completion_timeout(&ar->thermal.wmi_sync,
0090 ATH10K_THERMAL_SYNC_TIMEOUT_HZ);
0091 if (!time_left) {
0092 ath10k_warn(ar, "failed to synchronize thermal read\n");
0093 ret = -ETIMEDOUT;
0094 goto out;
0095 }
0096
0097 spin_lock_bh(&ar->data_lock);
0098 temperature = ar->thermal.temperature;
0099 spin_unlock_bh(&ar->data_lock);
0100
0101
0102 ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000);
0103 out:
0104 mutex_unlock(&ar->conf_mutex);
0105 return ret;
0106 }
0107
0108 void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature)
0109 {
0110 spin_lock_bh(&ar->data_lock);
0111 ar->thermal.temperature = temperature;
0112 spin_unlock_bh(&ar->data_lock);
0113 complete(&ar->thermal.wmi_sync);
0114 }
0115
0116 static SENSOR_DEVICE_ATTR(temp1_input, 0444, ath10k_thermal_show_temp,
0117 NULL, 0);
0118
0119 static struct attribute *ath10k_hwmon_attrs[] = {
0120 &sensor_dev_attr_temp1_input.dev_attr.attr,
0121 NULL,
0122 };
0123 ATTRIBUTE_GROUPS(ath10k_hwmon);
0124
0125 void ath10k_thermal_set_throttling(struct ath10k *ar)
0126 {
0127 u32 period, duration, enabled;
0128 int ret;
0129
0130 lockdep_assert_held(&ar->conf_mutex);
0131
0132 if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
0133 return;
0134
0135 if (!ar->wmi.ops->gen_pdev_set_quiet_mode)
0136 return;
0137
0138 if (ar->state != ATH10K_STATE_ON)
0139 return;
0140
0141 period = ar->thermal.quiet_period;
0142 duration = (period * ar->thermal.throttle_state) / 100;
0143 enabled = duration ? 1 : 0;
0144
0145 ret = ath10k_wmi_pdev_set_quiet_mode(ar, period, duration,
0146 ATH10K_QUIET_START_OFFSET,
0147 enabled);
0148 if (ret) {
0149 ath10k_warn(ar, "failed to set quiet mode period %u duarion %u enabled %u ret %d\n",
0150 period, duration, enabled, ret);
0151 }
0152 }
0153
0154 int ath10k_thermal_register(struct ath10k *ar)
0155 {
0156 struct thermal_cooling_device *cdev;
0157 struct device *hwmon_dev;
0158 int ret;
0159
0160 if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
0161 return 0;
0162
0163 cdev = thermal_cooling_device_register("ath10k_thermal", ar,
0164 &ath10k_thermal_ops);
0165
0166 if (IS_ERR(cdev)) {
0167 ath10k_err(ar, "failed to setup thermal device result: %ld\n",
0168 PTR_ERR(cdev));
0169 return -EINVAL;
0170 }
0171
0172 ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj,
0173 "cooling_device");
0174 if (ret) {
0175 ath10k_err(ar, "failed to create cooling device symlink\n");
0176 goto err_cooling_destroy;
0177 }
0178
0179 ar->thermal.cdev = cdev;
0180 ar->thermal.quiet_period = ATH10K_QUIET_PERIOD_DEFAULT;
0181
0182
0183
0184
0185 if (!(ar->wmi.ops->gen_pdev_get_temperature))
0186 return 0;
0187
0188
0189
0190
0191 if (!IS_REACHABLE(CONFIG_HWMON))
0192 return 0;
0193
0194 hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev,
0195 "ath10k_hwmon", ar,
0196 ath10k_hwmon_groups);
0197 if (IS_ERR(hwmon_dev)) {
0198 ath10k_err(ar, "failed to register hwmon device: %ld\n",
0199 PTR_ERR(hwmon_dev));
0200 ret = -EINVAL;
0201 goto err_remove_link;
0202 }
0203 return 0;
0204
0205 err_remove_link:
0206 sysfs_remove_link(&ar->dev->kobj, "cooling_device");
0207 err_cooling_destroy:
0208 thermal_cooling_device_unregister(cdev);
0209 return ret;
0210 }
0211
0212 void ath10k_thermal_unregister(struct ath10k *ar)
0213 {
0214 if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
0215 return;
0216
0217 sysfs_remove_link(&ar->dev->kobj, "cooling_device");
0218 thermal_cooling_device_unregister(ar->thermal.cdev);
0219 }