From d671bf70bafbce61f03508c88ae2a30015b44277 Mon Sep 17 00:00:00 2001 From: Alex Naidis Date: Mon, 11 Sep 2017 09:46:30 -0400 Subject: [PATCH] msm-tsens: Reschedule work instead of causing uninterruptible sleep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tsens_poll work causes uninterruptible sleep on the UI thread and thus blocks other tasks from running due to the msleep call. To avoid this condition, we introduce a variable to hold the staging state of the critical polling and reschedule the work itself to be executed again after the same duration as the msleep. Additionally we switch the currently unused wq to a singlethreaded wq and queue the tsens work onto that wq. Change-Id: I0bf48837310decd035d35ac78aa7d51614032b36 Signed-off-by: Alex Naidis Signed-off-by: Ícaro Hoff --- drivers/thermal/msm-tsens.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c index ea1fee6732ef..7a158210e1b9 100644 --- a/drivers/thermal/msm-tsens.c +++ b/drivers/thermal/msm-tsens.c @@ -867,6 +867,7 @@ struct tsens_tm_device { u64 qtimer_val_last_detection_interrupt; u64 qtimer_val_last_polling_check; bool tsens_critical_poll; + bool tsens_critical_poll_state; struct tsens_tm_device_sensor sensor[0]; }; @@ -2010,7 +2011,7 @@ static void tsens_poll(struct work_struct *work) unsigned int debug_id = 0, cntrl_id = 0; uint32_t r1, r2, r3, r4, offset = 0, idx = 0; unsigned long temp, flags; - unsigned int status, int_mask, int_mask_val; + unsigned int status, int_mask, int_mask_val, resched_ms; void __iomem *srot_addr; void __iomem *controller_id_addr; void __iomem *debug_id_addr; @@ -2034,6 +2035,10 @@ static void tsens_poll(struct work_struct *work) /* Sensor 0 on either of the controllers */ mask = 0; + if (tmdev->tsens_critical_poll_state) { + goto critical_poll; + } + reinit_completion(&tmdev->tsens_rslt_completion); temp &= TSENS_TM_SN_CRITICAL_THRESHOLD_MASK; @@ -2069,8 +2074,12 @@ static void tsens_poll(struct work_struct *work) } spin_unlock_irqrestore(&tmdev->tsens_crit_lock, flags); - if (tmdev->tsens_critical_poll) { - msleep(TSENS_DEBUG_POLL_MS); +critical_poll: + if (tmdev->tsens_critical_poll && !tmdev->tsens_critical_poll_state) { + tmdev->tsens_critical_poll_state = true; + goto re_schedule; + } else if (tmdev->tsens_critical_poll) { + tmdev->tsens_critical_poll_state = false; sensor_status_addr = TSENS_TM_SN_STATUS(tmdev->tsens_addr); spin_lock_irqsave(&tmdev->tsens_crit_lock, flags); @@ -2230,9 +2239,11 @@ static void tsens_poll(struct work_struct *work) } re_schedule: - - schedule_delayed_work(&tmdev->tsens_critical_poll_test, - msecs_to_jiffies(tsens_sec_to_msec_value)); + resched_ms = tmdev->tsens_critical_poll_state + ? TSENS_DEBUG_POLL_MS : tsens_sec_to_msec_value; + queue_delayed_work(tmdev->tsens_critical_wq, + &tmdev->tsens_critical_poll_test, + msecs_to_jiffies(resched_ms)); } int tsens_mtc_reset_history_counter(unsigned int zone) @@ -5744,8 +5755,8 @@ static int tsens_tm_probe(struct platform_device *pdev) tmdev->pdev = pdev; - tmdev->tsens_critical_wq = alloc_workqueue("tsens_critical_wq", - WQ_HIGHPRI, 0); + tmdev->tsens_critical_wq = create_singlethread_workqueue("tsens_critical_wq"); + if (!tmdev->tsens_critical_wq) { rc = -ENOMEM; goto fail; @@ -5770,6 +5781,7 @@ static int tsens_tm_probe(struct platform_device *pdev) spin_lock_init(&tmdev->tsens_upp_low_lock); spin_lock_init(&tmdev->tsens_debug_lock); + tmdev->tsens_critical_poll_state = false; tmdev->is_ready = true; list_add_tail(&tmdev->list, &tsens_device_list); @@ -5938,7 +5950,8 @@ static int tsens_thermal_zone_register(struct tsens_tm_device *tmdev) if (tsens_poll_check) { INIT_DEFERRABLE_WORK(&tmdev->tsens_critical_poll_test, tsens_poll); - schedule_delayed_work(&tmdev->tsens_critical_poll_test, + queue_delayed_work(tmdev->tsens_critical_wq, + &tmdev->tsens_critical_poll_test, msecs_to_jiffies(tsens_sec_to_msec_value)); init_completion(&tmdev->tsens_rslt_completion); tmdev->tsens_critical_poll = true;