diff options
| author | Joshua Primero <jprimero@nvidia.com> | 2012-10-16 20:29:14 -0400 |
|---|---|---|
| committer | Nicolin Chen <nicolinc@nvidia.com> | 2017-08-14 21:38:52 -0400 |
| commit | 5429460bed4b231e0755682366d98a5b9c2d8b26 (patch) | |
| tree | 1a26b52365bd6efe0e8fab12c9eaff55949f0ebe | |
| parent | aa089187e0530ab733c85beb0cc6ff10a35e0a28 (diff) | |
drivers: misc: therm_est: add debug sysfs nodes
Added the ability change coefficients and offset during runtime.
This is found in /sys/devices/therm_est/coeffs and
/sys/devices/therm_est/offset.
Also, added the ability to view the history of temperatures
per device used by the therm_est driver. This is found in
/sys/devices/therm_est/temps.
bug 1158994
bug 1059470
Change-Id: Ie3441a2c9a613381d4e19c61479001975488fd76
Signed-off-by: Joshua Primero <jprimero@nvidia.com>
Reviewed-on: http://git-master/r/145060
(cherry picked from commit ee1078d1262fd0f01d156796837c3c67f92d3873)
Signed-off-by: Gaurav Batra <gbatra@nvidia.com>
Reviewed-on: http://git-master/r/147060
Rebase-Id: Rf68a5473fa9ebe40ff38c8337689b0b14ea04f63
| -rw-r--r-- | drivers/misc/therm_est.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/drivers/misc/therm_est.c b/drivers/misc/therm_est.c index 0bef8fbb7..8e6ace29f 100644 --- a/drivers/misc/therm_est.c +++ b/drivers/misc/therm_est.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/therm_est.h> | 30 | #include <linux/therm_est.h> |
| 31 | #include <linux/thermal.h> | 31 | #include <linux/thermal.h> |
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <linux/hwmon-sysfs.h> | ||
| 33 | 34 | ||
| 34 | struct therm_estimator { | 35 | struct therm_estimator { |
| 35 | long cur_temp; | 36 | long cur_temp; |
| @@ -139,6 +140,128 @@ static struct thermal_zone_device_ops therm_est_ops = { | |||
| 139 | .get_temp = therm_est_get_temp, | 140 | .get_temp = therm_est_get_temp, |
| 140 | }; | 141 | }; |
| 141 | 142 | ||
| 143 | static ssize_t show_coeff(struct device *dev, | ||
| 144 | struct device_attribute *da, | ||
| 145 | char *buf) | ||
| 146 | { | ||
| 147 | struct therm_estimator *est = dev_get_drvdata(dev); | ||
| 148 | ssize_t len, total_len = 0; | ||
| 149 | int i, j; | ||
| 150 | for (i = 0; i < est->ndevs; i++) { | ||
| 151 | len = snprintf(buf + total_len, PAGE_SIZE, "[%d]", i); | ||
| 152 | total_len += len; | ||
| 153 | for (j = 0; j < HIST_LEN; j++) { | ||
| 154 | len = snprintf(buf + total_len, PAGE_SIZE, " %ld", | ||
| 155 | est->devs[i].coeffs[j]); | ||
| 156 | total_len += len; | ||
| 157 | } | ||
| 158 | len = snprintf(buf + total_len, PAGE_SIZE, "\n"); | ||
| 159 | total_len += len; | ||
| 160 | } | ||
| 161 | return strlen(buf); | ||
| 162 | } | ||
| 163 | |||
| 164 | static ssize_t set_coeff(struct device *dev, | ||
| 165 | struct device_attribute *da, | ||
| 166 | const char *buf, size_t count) | ||
| 167 | { | ||
| 168 | struct therm_estimator *est = dev_get_drvdata(dev); | ||
| 169 | int devid, scount; | ||
| 170 | long coeff[20]; | ||
| 171 | |||
| 172 | if (HIST_LEN > 20) | ||
| 173 | return -EINVAL; | ||
| 174 | |||
| 175 | scount = sscanf(buf, "[%d] %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld " \ | ||
| 176 | "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", | ||
| 177 | &devid, | ||
| 178 | &coeff[0], | ||
| 179 | &coeff[1], | ||
| 180 | &coeff[2], | ||
| 181 | &coeff[3], | ||
| 182 | &coeff[4], | ||
| 183 | &coeff[5], | ||
| 184 | &coeff[6], | ||
| 185 | &coeff[7], | ||
| 186 | &coeff[8], | ||
| 187 | &coeff[9], | ||
| 188 | &coeff[10], | ||
| 189 | &coeff[11], | ||
| 190 | &coeff[12], | ||
| 191 | &coeff[13], | ||
| 192 | &coeff[14], | ||
| 193 | &coeff[15], | ||
| 194 | &coeff[16], | ||
| 195 | &coeff[17], | ||
| 196 | &coeff[18], | ||
| 197 | &coeff[19]); | ||
| 198 | |||
| 199 | if (scount != HIST_LEN + 1) | ||
| 200 | return -1; | ||
| 201 | |||
| 202 | if (devid < 0 || devid >= est->ndevs) | ||
| 203 | return -EINVAL; | ||
| 204 | |||
| 205 | /* This has obvious locking issues but don't worry about it */ | ||
| 206 | memcpy(est->devs[devid].coeffs, coeff, sizeof(long) * HIST_LEN); | ||
| 207 | |||
| 208 | return count; | ||
| 209 | } | ||
| 210 | |||
| 211 | static ssize_t show_offset(struct device *dev, | ||
| 212 | struct device_attribute *da, | ||
| 213 | char *buf) | ||
| 214 | { | ||
| 215 | struct therm_estimator *est = dev_get_drvdata(dev); | ||
| 216 | snprintf(buf, PAGE_SIZE, "%ld\n", est->toffset); | ||
| 217 | return strlen(buf); | ||
| 218 | } | ||
| 219 | |||
| 220 | static ssize_t set_offset(struct device *dev, | ||
| 221 | struct device_attribute *da, | ||
| 222 | const char *buf, size_t count) | ||
| 223 | { | ||
| 224 | struct therm_estimator *est = dev_get_drvdata(dev); | ||
| 225 | int offset; | ||
| 226 | |||
| 227 | if (kstrtoint(buf, 0, &offset)) | ||
| 228 | return -EINVAL; | ||
| 229 | |||
| 230 | est->toffset = offset; | ||
| 231 | |||
| 232 | return count; | ||
| 233 | } | ||
| 234 | |||
| 235 | static ssize_t show_temps(struct device *dev, | ||
| 236 | struct device_attrbite *da, | ||
| 237 | char *buf) | ||
| 238 | { | ||
| 239 | struct therm_estimator *est = dev_get_drvdata(dev); | ||
| 240 | ssize_t total_len = 0; | ||
| 241 | int i, j; | ||
| 242 | int index; | ||
| 243 | |||
| 244 | /* This has obvious locking issues but don't worry about it */ | ||
| 245 | for (i = 0; i < est->ndevs; i++) { | ||
| 246 | total_len += snprintf(buf + total_len, PAGE_SIZE, "[%d]", i); | ||
| 247 | for (j = 0; j < HIST_LEN; j++) { | ||
| 248 | index = (est->ntemp - j + HIST_LEN) % HIST_LEN; | ||
| 249 | total_len += snprintf(buf + total_len, | ||
| 250 | PAGE_SIZE, | ||
| 251 | " %ld", | ||
| 252 | est->devs[i].hist[index]); | ||
| 253 | } | ||
| 254 | total_len += snprintf(buf + total_len, PAGE_SIZE, "\n"); | ||
| 255 | } | ||
| 256 | return strlen(buf); | ||
| 257 | } | ||
| 258 | |||
| 259 | static struct sensor_device_attribute therm_est_nodes[] = { | ||
| 260 | SENSOR_ATTR(coeff, S_IRUGO | S_IWUSR, show_coeff, set_coeff, 0), | ||
| 261 | SENSOR_ATTR(offset, S_IRUGO | S_IWUSR, show_offset, set_offset, 0), | ||
| 262 | SENSOR_ATTR(temps, S_IRUGO, show_temps, 0, 0), | ||
| 263 | }; | ||
| 264 | |||
| 142 | static int __devinit therm_est_probe(struct platform_device *pdev) | 265 | static int __devinit therm_est_probe(struct platform_device *pdev) |
| 143 | { | 266 | { |
| 144 | int i, j; | 267 | int i, j; |
| @@ -193,6 +316,9 @@ static int __devinit therm_est_probe(struct platform_device *pdev) | |||
| 193 | if (IS_ERR_OR_NULL(est->thz)) | 316 | if (IS_ERR_OR_NULL(est->thz)) |
| 194 | goto err; | 317 | goto err; |
| 195 | 318 | ||
| 319 | for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++) | ||
| 320 | device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr); | ||
| 321 | |||
| 196 | return 0; | 322 | return 0; |
| 197 | err: | 323 | err: |
| 198 | kfree(est); | 324 | kfree(est); |
