aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch')
-rw-r--r--target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch121
1 files changed, 121 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch b/target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch
new file mode 100644
index 0000000000..ab1dc23a5e
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch
@@ -0,0 +1,121 @@
+From b5157050b90e884345d1d5ca9662cb8686f72b4a Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Tue, 29 Jan 2019 15:56:10 +0000
+Subject: [PATCH 327/725] media:bcm2835-unicam: Power on subdev on
+ open/release, not streaming
+
+The driver was powering on the source subdevice as part of STREAMON,
+and powering it off in STREAMOFF. This isn't so great if there is a
+significant amount of setup required for your device.
+
+Copy the approach taken in the Atmel ISC driver where s_power(1) is called
+on first file handle open, and s_power(0) is called on the last release.
+
+See https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=232437
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ .../media/platform/bcm2835/bcm2835-unicam.c | 68 +++++++++++++++----
+ 1 file changed, 54 insertions(+), 14 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -1237,11 +1237,6 @@ static int unicam_start_streaming(struct
+ unicam_err(dev, "Failed to enable CSI clock: %d\n", ret);
+ goto err_pm_put;
+ }
+- ret = v4l2_subdev_call(dev->sensor, core, s_power, 1);
+- if (ret < 0 && ret != -ENOIOCTLCMD) {
+- unicam_err(dev, "power on failed in subdev\n");
+- goto err_clock_unprepare;
+- }
+ dev->streaming = 1;
+
+ unicam_start_rx(dev, addr);
+@@ -1256,8 +1251,6 @@ static int unicam_start_streaming(struct
+
+ err_disable_unicam:
+ unicam_disable(dev);
+- v4l2_subdev_call(dev->sensor, core, s_power, 0);
+-err_clock_unprepare:
+ clk_disable_unprepare(dev->clock);
+ err_pm_put:
+ unicam_runtime_put(dev);
+@@ -1306,11 +1299,6 @@ static void unicam_stop_streaming(struct
+ dev->next_frm = NULL;
+ spin_unlock_irqrestore(&dev->dma_queue_lock, flags);
+
+- if (v4l2_subdev_has_op(dev->sensor, core, s_power)) {
+- if (v4l2_subdev_call(dev->sensor, core, s_power, 0) < 0)
+- unicam_err(dev, "power off failed in subdev\n");
+- }
+-
+ clk_disable_unprepare(dev->clock);
+ unicam_runtime_put(dev);
+ }
+@@ -1543,11 +1531,63 @@ static const struct vb2_ops unicam_video
+ .stop_streaming = unicam_stop_streaming,
+ };
+
++/*
++ * unicam_open : This function is based on the v4l2_fh_open helper function.
++ * It has been augmented to handle sensor subdevice power management,
++ */
++static int unicam_open(struct file *file)
++{
++ struct unicam_device *dev = video_drvdata(file);
++ int ret;
++
++ mutex_lock(&dev->lock);
++
++ ret = v4l2_fh_open(file);
++ if (ret) {
++ unicam_err(dev, "v4l2_fh_open failed\n");
++ goto unlock;
++ }
++
++ if (!v4l2_fh_is_singular_file(file))
++ goto unlock;
++
++ ret = v4l2_subdev_call(dev->sensor, core, s_power, 1);
++ if (ret < 0 && ret != -ENOIOCTLCMD) {
++ v4l2_fh_release(file);
++ goto unlock;
++ }
++
++unlock:
++ mutex_unlock(&dev->lock);
++ return ret;
++}
++
++static int unicam_release(struct file *file)
++{
++ struct unicam_device *dev = video_drvdata(file);
++ struct v4l2_subdev *sd = dev->sensor;
++ bool fh_singular;
++ int ret;
++
++ mutex_lock(&dev->lock);
++
++ fh_singular = v4l2_fh_is_singular_file(file);
++
++ ret = _vb2_fop_release(file, NULL);
++
++ if (fh_singular)
++ v4l2_subdev_call(sd, core, s_power, 0);
++
++ mutex_unlock(&dev->lock);
++
++ return ret;
++}
++
+ /* unicam capture driver file operations */
+ static const struct v4l2_file_operations unicam_fops = {
+ .owner = THIS_MODULE,
+- .open = v4l2_fh_open,
+- .release = vb2_fop_release,
++ .open = unicam_open,
++ .release = unicam_release,
+ .read = vb2_fop_read,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,