aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2018-05-20 11:40:38 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-05-28 16:24:30 -0400
commit94ae1d6ba64c7157a6ba12a0deb7d8d7328fe4d5 (patch)
treed9ef1c9dfb1ad7543b31d3cadbd151af0a21bd65 /drivers/media
parentf68bbb23259e59e31ab52d240761973dfc9697d8 (diff)
media: pxa_camera: avoid duplicate s_power calls
The open() operation for the pxa_camera driver always calls s_power() operation to put its subdevice sensor in normal operation mode, and the release() operation always call s_power() operation to put the subdevice in power saving mode. This requires the subdevice sensor driver to keep track of its power state in order to avoid putting the subdevice in power saving mode while the device is still opened by some users. Many subdevice drivers handle it by the boilerplate code that increments and decrements an internal counter in s_power() like below: /* * If the power count is modified from 0 to != 0 or from != 0 to 0, * update the power state. */ if (sensor->power_count == !on) { ret = ov5640_set_power(sensor, !!on); if (ret) goto out; } /* Update the power count. */ sensor->power_count += on ? 1 : -1; However, some subdevice drivers don't handle it and may cause a problem with the pxa_camera driver if the video device is opened by more than two users at the same time. Instead of propagating the boilerplate code for each subdevice driver that implement s_power, this introduces an trick that many V4L2 drivers are using with v4l2_fh_is_singular_file(). Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/pxa_camera.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index c71a00736541..c792cb178a84 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -2040,6 +2040,9 @@ static int pxac_fops_camera_open(struct file *filp)
2040 if (ret < 0) 2040 if (ret < 0)
2041 goto out; 2041 goto out;
2042 2042
2043 if (!v4l2_fh_is_singular_file(filp))
2044 goto out;
2045
2043 ret = sensor_call(pcdev, core, s_power, 1); 2046 ret = sensor_call(pcdev, core, s_power, 1);
2044 if (ret) 2047 if (ret)
2045 v4l2_fh_release(filp); 2048 v4l2_fh_release(filp);
@@ -2052,13 +2055,17 @@ static int pxac_fops_camera_release(struct file *filp)
2052{ 2055{
2053 struct pxa_camera_dev *pcdev = video_drvdata(filp); 2056 struct pxa_camera_dev *pcdev = video_drvdata(filp);
2054 int ret; 2057 int ret;
2055 2058 bool fh_singular;
2056 ret = vb2_fop_release(filp);
2057 if (ret < 0)
2058 return ret;
2059 2059
2060 mutex_lock(&pcdev->mlock); 2060 mutex_lock(&pcdev->mlock);
2061 ret = sensor_call(pcdev, core, s_power, 0); 2061
2062 fh_singular = v4l2_fh_is_singular_file(filp);
2063
2064 ret = _vb2_fop_release(filp, NULL);
2065
2066 if (fh_singular)
2067 ret = sensor_call(pcdev, core, s_power, 0);
2068
2062 mutex_unlock(&pcdev->mlock); 2069 mutex_unlock(&pcdev->mlock);
2063 2070
2064 return ret; 2071 return ret;