diff options
| author | Hyungwoo Yang <hyungwooy@nvidia.com> | 2014-01-28 20:31:44 -0500 |
|---|---|---|
| committer | Nicolin Chen <nicolinc@nvidia.com> | 2017-08-14 21:38:52 -0400 |
| commit | 1d4e6deb97f650950cd4cbecc3e3ec8db55e8dfd (patch) | |
| tree | a1a482e4ba0fafb53eebfd8eb82eaa096bf8b321 | |
| parent | 41174a0a754f2884f2e2b62c12d578637d44e3cf (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.c | 20 | ||||
| -rw-r--r-- | include/linux/therm_est.h | 1 |
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 | ||
| 111 | static int therm_est_subdev_get_temp(void *data, long *temp) | 111 | static 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 | ||
| 29 | struct therm_est_subdevice { | 29 | struct 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 | }; |
