summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHyungwoo Yang <hyungwooy@nvidia.com>2014-01-28 20:31:44 -0500
committerNicolin Chen <nicolinc@nvidia.com>2017-08-14 21:38:52 -0400
commit1d4e6deb97f650950cd4cbecc3e3ec8db55e8dfd (patch)
treea1a482e4ba0fafb53eebfd8eb82eaa096bf8b321
parent41174a0a754f2884f2e2b62c12d578637d44e3cf (diff)
ARM: tegra: thermal: fix therm_est_activ polling
During bootup, deadlock happens with "thermal_list_lock" while trying to finding zones for sub_devs. This change fixes the deadlock issue and also removes zone lookup which happens on every temperature reading. Bug 1415692 Change-Id: I13a81de7ef9051e8d7a0fe0f2c59febdea0fa1d5 Signed-off-by: Hyungwoo Yang <hyungwooy@nvidia.com> Reviewed-on: http://git-master/r/361188
-rw-r--r--drivers/misc/therm_est.c20
-rw-r--r--include/linux/therm_est.h1
2 files changed, 14 insertions, 7 deletions
diff --git a/drivers/misc/therm_est.c b/drivers/misc/therm_est.c
index c4dfbdab6..471d626ff 100644
--- a/drivers/misc/therm_est.c
+++ b/drivers/misc/therm_est.c
@@ -108,12 +108,9 @@ static int therm_est_subdev_match(struct thermal_zone_device *thz, void *data)
108 return strcmp((char *)data, thz->type) == 0; 108 return strcmp((char *)data, thz->type) == 0;
109} 109}
110 110
111static int therm_est_subdev_get_temp(void *data, long *temp) 111static int therm_est_subdev_get_temp(struct thermal_zone_device *thz,
112 long *temp)
112{ 113{
113 struct thermal_zone_device *thz;
114
115 thz = thermal_zone_device_find(data, therm_est_subdev_match);
116
117 if (!thz || thz->ops->get_temp(thz, temp)) 114 if (!thz || thz->ops->get_temp(thz, temp))
118 *temp = 25000; 115 *temp = 25000;
119 116
@@ -249,7 +246,7 @@ static void therm_est_work_func(struct work_struct *work)
249 therm_est_work); 246 therm_est_work);
250 247
251 for (i = 0; i < est->ndevs; i++) { 248 for (i = 0; i < est->ndevs; i++) {
252 if (therm_est_subdev_get_temp(est->devs[i].dev_data, &temp)) 249 if (therm_est_subdev_get_temp(est->devs[i].sub_thz, &temp))
253 continue; 250 continue;
254 est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp; 251 est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp;
255 } 252 }
@@ -475,7 +472,7 @@ static int therm_est_init_history(struct therm_estimator *est)
475 for (i = 0; i < est->ndevs; i++) { 472 for (i = 0; i < est->ndevs; i++) {
476 dev = &est->devs[i]; 473 dev = &est->devs[i];
477 474
478 if (therm_est_subdev_get_temp(dev->dev_data, &temp)) 475 if (therm_est_subdev_get_temp(dev->sub_thz, &temp))
479 return -EINVAL; 476 return -EINVAL;
480 477
481 for (j = 0; j < HIST_LEN; j++) 478 for (j = 0; j < HIST_LEN; j++)
@@ -777,6 +774,7 @@ static int therm_est_probe(struct platform_device *pdev)
777 int i; 774 int i;
778 struct therm_estimator *est; 775 struct therm_estimator *est;
779 struct therm_est_data *data; 776 struct therm_est_data *data;
777 struct thermal_zone_device *thz;
780 778
781 est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL); 779 est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
782 if (IS_ERR_OR_NULL(est)) 780 if (IS_ERR_OR_NULL(est))
@@ -786,6 +784,14 @@ static int therm_est_probe(struct platform_device *pdev)
786 784
787 data = pdev->dev.platform_data; 785 data = pdev->dev.platform_data;
788 786
787 for (i = 0; i < data->ndevs; i++) {
788 thz = thermal_zone_device_find(data->devs[i].dev_data,
789 therm_est_subdev_match);
790 if (!thz)
791 goto err;
792 data->devs[i].sub_thz = thz;
793 }
794
789 est->devs = data->devs; 795 est->devs = data->devs;
790 est->ndevs = data->ndevs; 796 est->ndevs = data->ndevs;
791 est->toffset = data->toffset; 797 est->toffset = data->toffset;
diff --git a/include/linux/therm_est.h b/include/linux/therm_est.h
index 7526aa9b7..b89ca44cb 100644
--- a/include/linux/therm_est.h
+++ b/include/linux/therm_est.h
@@ -28,6 +28,7 @@
28 28
29struct therm_est_subdevice { 29struct therm_est_subdevice {
30 void *dev_data; 30 void *dev_data;
31 struct thermal_zone_device *sub_thz;
31 long coeffs[HIST_LEN]; 32 long coeffs[HIST_LEN];
32 long hist[HIST_LEN]; 33 long hist[HIST_LEN];
33}; 34};