summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Primero <jprimero@nvidia.com>2012-10-16 20:29:14 -0400
committerNicolin Chen <nicolinc@nvidia.com>2017-08-14 21:38:52 -0400
commit5429460bed4b231e0755682366d98a5b9c2d8b26 (patch)
tree1a26b52365bd6efe0e8fab12c9eaff55949f0ebe
parentaa089187e0530ab733c85beb0cc6ff10a35e0a28 (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.c126
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
34struct therm_estimator { 35struct 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
143static 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
164static 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
211static 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
220static 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
235static 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
259static 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
142static int __devinit therm_est_probe(struct platform_device *pdev) 265static 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;
197err: 323err:
198 kfree(est); 324 kfree(est);