diff mbox series

[3/3] hwmon: bt1-pvt: Wait for the completion with timeout

Message ID 20200920110924.19741-4-Sergey.Semin@baikalelectronics.ru (mailing list archive)
State Not Applicable
Headers show
Series hwmon: bt1-pvt: Fix PVT sensor being unpowered | expand

Commit Message

Serge Semin Sept. 20, 2020, 11:09 a.m. UTC
If the PVT sensor is suddenly powered down while a caller is waiting for
the conversion completion, the request won't be finished and the task will
hang up on this procedure until the power is back up again. Let's call the
wait_for_completion_timeout() method instead to prevent that. The cached
timeout is exactly what we need to predict for how long conversion could
normally last.

Fixes: 87976ce2825d ("hwmon: Add Baikal-T1 PVT sensor driver")
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
---
 drivers/hwmon/bt1-pvt.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Comments

Guenter Roeck Oct. 2, 2020, 4:15 p.m. UTC | #1
On Sun, Sep 20, 2020 at 02:09:23PM +0300, Serge Semin wrote:
> If the PVT sensor is suddenly powered down while a caller is waiting for
> the conversion completion, the request won't be finished and the task will
> hang up on this procedure until the power is back up again. Let's call the
> wait_for_completion_timeout() method instead to prevent that. The cached
> timeout is exactly what we need to predict for how long conversion could
> normally last.
> 
> Fixes: 87976ce2825d ("hwmon: Add Baikal-T1 PVT sensor driver")
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>

Applied.

Thanks,
Guenter

> ---
>  drivers/hwmon/bt1-pvt.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwmon/bt1-pvt.c b/drivers/hwmon/bt1-pvt.c
> index 2600426a3b21..3e1d56585b91 100644
> --- a/drivers/hwmon/bt1-pvt.c
> +++ b/drivers/hwmon/bt1-pvt.c
> @@ -477,6 +477,7 @@ static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
>  			 long *val)
>  {
>  	struct pvt_cache *cache = &pvt->cache[type];
> +	unsigned long timeout;
>  	u32 data;
>  	int ret;
>  
> @@ -500,7 +501,14 @@ static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
>  	pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0);
>  	pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
>  
> -	wait_for_completion(&cache->conversion);
> +	/*
> +	 * Wait with timeout since in case if the sensor is suddenly powered
> +	 * down the request won't be completed and the caller will hang up on
> +	 * this procedure until the power is back up again. Multiply the
> +	 * timeout by the factor of two to prevent a false timeout.
> +	 */
> +	timeout = 2 * usecs_to_jiffies(ktime_to_us(pvt->timeout));
> +	ret = wait_for_completion_timeout(&cache->conversion, timeout);
>  
>  	pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
>  	pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
> @@ -510,6 +518,9 @@ static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
>  
>  	mutex_unlock(&pvt->iface_mtx);
>  
> +	if (!ret)
> +		return -ETIMEDOUT;
> +
>  	if (type == PVT_TEMP)
>  		*val = pvt_calc_poly(&poly_N_to_temp, data);
>  	else
diff mbox series

Patch

diff --git a/drivers/hwmon/bt1-pvt.c b/drivers/hwmon/bt1-pvt.c
index 2600426a3b21..3e1d56585b91 100644
--- a/drivers/hwmon/bt1-pvt.c
+++ b/drivers/hwmon/bt1-pvt.c
@@ -477,6 +477,7 @@  static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
 			 long *val)
 {
 	struct pvt_cache *cache = &pvt->cache[type];
+	unsigned long timeout;
 	u32 data;
 	int ret;
 
@@ -500,7 +501,14 @@  static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
 	pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0);
 	pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
 
-	wait_for_completion(&cache->conversion);
+	/*
+	 * Wait with timeout since in case if the sensor is suddenly powered
+	 * down the request won't be completed and the caller will hang up on
+	 * this procedure until the power is back up again. Multiply the
+	 * timeout by the factor of two to prevent a false timeout.
+	 */
+	timeout = 2 * usecs_to_jiffies(ktime_to_us(pvt->timeout));
+	ret = wait_for_completion_timeout(&cache->conversion, timeout);
 
 	pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
 	pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
@@ -510,6 +518,9 @@  static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
 
 	mutex_unlock(&pvt->iface_mtx);
 
+	if (!ret)
+		return -ETIMEDOUT;
+
 	if (type == PVT_TEMP)
 		*val = pvt_calc_poly(&poly_N_to_temp, data);
 	else