diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-4.19/950-0282-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-4.19/950-0282-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-4.19/950-0282-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch b/target/linux/bcm27xx/patches-4.19/950-0282-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch new file mode 100644 index 0000000000..0946b77037 --- /dev/null +++ b/target/linux/bcm27xx/patches-4.19/950-0282-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch @@ -0,0 +1,121 @@ +From bf1805e0c8c4fc05e2a13b0a03b510ff4e523418 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] 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, |