public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [media] adv7180: free an interrupt on failure paths in init_device()
@ 2014-03-14 21:04 Alexey Khoroshilov
  2014-03-21  7:56 ` Lars-Peter Clausen
  0 siblings, 1 reply; 2+ messages in thread
From: Alexey Khoroshilov @ 2014-03-14 21:04 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Alexey Khoroshilov, Hans Verkuil, linux-media, linux-kernel,
	ldv-project

There is request_irq() in init_device(), but the interrupt is not removed
on failure paths. The patch adds proper error handling.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
 drivers/media/i2c/adv7180.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index d7d99f1c69e4..e462392ba043 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -541,40 +541,44 @@ static int init_device(struct i2c_client *client, struct adv7180_state *state)
 		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
 						ADV7180_ADI_CTRL_IRQ_SPACE);
 		if (ret < 0)
-			return ret;
+			goto err;
 
 		/* config the Interrupt pin to be active low */
 		ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
 						ADV7180_ICONF1_ACTIVE_LOW |
 						ADV7180_ICONF1_PSYNC_ONLY);
 		if (ret < 0)
-			return ret;
+			goto err;
 
 		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
 		if (ret < 0)
-			return ret;
+			goto err;
 
 		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
 		if (ret < 0)
-			return ret;
+			goto err;
 
 		/* enable AD change interrupts interrupts */
 		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
 						ADV7180_IRQ3_AD_CHANGE);
 		if (ret < 0)
-			return ret;
+			goto err;
 
 		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
 		if (ret < 0)
-			return ret;
+			goto err;
 
 		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
 						0);
 		if (ret < 0)
-			return ret;
+			goto err;
 	}
 
 	return 0;
+
+err:
+	free_irq(state->irq, state);
+	return ret;
 }
 
 static int adv7180_probe(struct i2c_client *client,
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] [media] adv7180: free an interrupt on failure paths in init_device()
  2014-03-14 21:04 [PATCH] [media] adv7180: free an interrupt on failure paths in init_device() Alexey Khoroshilov
@ 2014-03-21  7:56 ` Lars-Peter Clausen
  0 siblings, 0 replies; 2+ messages in thread
From: Lars-Peter Clausen @ 2014-03-21  7:56 UTC (permalink / raw)
  To: Alexey Khoroshilov
  Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel,
	ldv-project

On 03/14/2014 10:04 PM, Alexey Khoroshilov wrote:
> There is request_irq() in init_device(), but the interrupt is not removed
> on failure paths. The patch adds proper error handling.
>
> Found by Linux Driver Verification project (linuxtesting.org).
>
> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>

Hi,

Thanks for the patch. It's actually worse than that. request_irq should not 
be called in init_device() since init_device() is also called on resume(). 
The request_irq call should be moved to probe() and be called after init 
device. I've recently made some modifications to this part of the driver 
(switched to threaded IRQs), so make sure you generate the patch against the 
media/master tree.

Thanks,
- Lars

> ---
>   drivers/media/i2c/adv7180.c | 18 +++++++++++-------
>   1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
> index d7d99f1c69e4..e462392ba043 100644
> --- a/drivers/media/i2c/adv7180.c
> +++ b/drivers/media/i2c/adv7180.c
> @@ -541,40 +541,44 @@ static int init_device(struct i2c_client *client, struct adv7180_state *state)
>   		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
>   						ADV7180_ADI_CTRL_IRQ_SPACE);
>   		if (ret < 0)
> -			return ret;
> +			goto err;
>
>   		/* config the Interrupt pin to be active low */
>   		ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
>   						ADV7180_ICONF1_ACTIVE_LOW |
>   						ADV7180_ICONF1_PSYNC_ONLY);
>   		if (ret < 0)
> -			return ret;
> +			goto err;
>
>   		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
>   		if (ret < 0)
> -			return ret;
> +			goto err;
>
>   		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
>   		if (ret < 0)
> -			return ret;
> +			goto err;
>
>   		/* enable AD change interrupts interrupts */
>   		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
>   						ADV7180_IRQ3_AD_CHANGE);
>   		if (ret < 0)
> -			return ret;
> +			goto err;
>
>   		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
>   		if (ret < 0)
> -			return ret;
> +			goto err;
>
>   		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
>   						0);
>   		if (ret < 0)
> -			return ret;
> +			goto err;
>   	}
>
>   	return 0;
> +
> +err:
> +	free_irq(state->irq, state);
> +	return ret;
>   }
>
>   static int adv7180_probe(struct i2c_client *client,
>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-03-21  7:55 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-14 21:04 [PATCH] [media] adv7180: free an interrupt on failure paths in init_device() Alexey Khoroshilov
2014-03-21  7:56 ` Lars-Peter Clausen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox