From 1d4e6deb97f650950cd4cbecc3e3ec8db55e8dfd Mon Sep 17 00:00:00 2001 From: Hyungwoo Yang Date: Tue, 28 Jan 2014 17:31:44 -0800 Subject: 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 Reviewed-on: http://git-master/r/361188 --- drivers/misc/therm_est.c | 20 +++++++++++++------- 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) return strcmp((char *)data, thz->type) == 0; } -static int therm_est_subdev_get_temp(void *data, long *temp) +static int therm_est_subdev_get_temp(struct thermal_zone_device *thz, + long *temp) { - struct thermal_zone_device *thz; - - thz = thermal_zone_device_find(data, therm_est_subdev_match); - if (!thz || thz->ops->get_temp(thz, temp)) *temp = 25000; @@ -249,7 +246,7 @@ static void therm_est_work_func(struct work_struct *work) therm_est_work); for (i = 0; i < est->ndevs; i++) { - if (therm_est_subdev_get_temp(est->devs[i].dev_data, &temp)) + if (therm_est_subdev_get_temp(est->devs[i].sub_thz, &temp)) continue; est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp; } @@ -475,7 +472,7 @@ static int therm_est_init_history(struct therm_estimator *est) for (i = 0; i < est->ndevs; i++) { dev = &est->devs[i]; - if (therm_est_subdev_get_temp(dev->dev_data, &temp)) + if (therm_est_subdev_get_temp(dev->sub_thz, &temp)) return -EINVAL; for (j = 0; j < HIST_LEN; j++) @@ -777,6 +774,7 @@ static int therm_est_probe(struct platform_device *pdev) int i; struct therm_estimator *est; struct therm_est_data *data; + struct thermal_zone_device *thz; est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL); if (IS_ERR_OR_NULL(est)) @@ -786,6 +784,14 @@ static int therm_est_probe(struct platform_device *pdev) data = pdev->dev.platform_data; + for (i = 0; i < data->ndevs; i++) { + thz = thermal_zone_device_find(data->devs[i].dev_data, + therm_est_subdev_match); + if (!thz) + goto err; + data->devs[i].sub_thz = thz; + } + est->devs = data->devs; est->ndevs = data->ndevs; 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 @@ struct therm_est_subdevice { void *dev_data; + struct thermal_zone_device *sub_thz; long coeffs[HIST_LEN]; long hist[HIST_LEN]; }; -- cgit v1.2.2