Commit 94ae1d6b authored by Akinobu Mita's avatar Akinobu Mita Committed by Mauro Carvalho Chehab

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: default avatarAkinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent f68bbb23
...@@ -2040,6 +2040,9 @@ static int pxac_fops_camera_open(struct file *filp) ...@@ -2040,6 +2040,9 @@ static int pxac_fops_camera_open(struct file *filp)
if (ret < 0) if (ret < 0)
goto out; goto out;
if (!v4l2_fh_is_singular_file(filp))
goto out;
ret = sensor_call(pcdev, core, s_power, 1); ret = sensor_call(pcdev, core, s_power, 1);
if (ret) if (ret)
v4l2_fh_release(filp); v4l2_fh_release(filp);
...@@ -2052,13 +2055,17 @@ static int pxac_fops_camera_release(struct file *filp) ...@@ -2052,13 +2055,17 @@ static int pxac_fops_camera_release(struct file *filp)
{ {
struct pxa_camera_dev *pcdev = video_drvdata(filp); struct pxa_camera_dev *pcdev = video_drvdata(filp);
int ret; int ret;
bool fh_singular;
ret = vb2_fop_release(filp);
if (ret < 0)
return ret;
mutex_lock(&pcdev->mlock); mutex_lock(&pcdev->mlock);
ret = sensor_call(pcdev, core, s_power, 0);
fh_singular = v4l2_fh_is_singular_file(filp);
ret = _vb2_fop_release(filp, NULL);
if (fh_singular)
ret = sensor_call(pcdev, core, s_power, 0);
mutex_unlock(&pcdev->mlock); mutex_unlock(&pcdev->mlock);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment