[PATCH] media: ov6650: Fix clock not released on subdev unregister

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit c62b96050bee ("media: ov6650: Register with asynchronous
subdevice framework") introduced an asymmetry in master clock get/put
operations.  A reference to the clock is taken as late as on V4L2
subdevice registration but released only on I2C device removal.  If
the subdevice is ever unregistered by its parent V4L2 device and re-
registered again without the driver being unbound and rebound back to
the I2C device, the clock reference will be taken multiple times and
never released.

As a fix, implement .unregistered() subdevice internal operation and
release the reference to the master clock from there.

Fixes: c62b96050bee ("media: ov6650: Register with asynchronous subdevice framework")
Signed-off-by: Janusz Krzysztofik <jmkrzyszt@xxxxxxxxx>
---
 drivers/media/i2c/ov6650.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c
index 91906b94f978..218c7af7a13a 100644
--- a/drivers/media/i2c/ov6650.c
+++ b/drivers/media/i2c/ov6650.c
@@ -986,8 +986,17 @@ static const struct v4l2_subdev_ops ov6650_subdev_ops = {
 	.pad	= &ov6650_pad_ops,
 };
 
+static void ov6650_unregistered(struct v4l2_subdev *sd)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov6650 *priv = to_ov6650(client);
+
+	v4l2_clk_put(priv->clk);
+}
+
 static const struct v4l2_subdev_internal_ops ov6650_internal_ops = {
 	.registered = ov6650_video_probe,
+	.unregistered = ov6650_unregistered,
 };
 
 /*
@@ -1068,7 +1077,6 @@ static int ov6650_remove(struct i2c_client *client)
 {
 	struct ov6650 *priv = to_ov6650(client);
 
-	v4l2_clk_put(priv->clk);
 	v4l2_async_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
-- 
2.24.1




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux