[PATCH] media: pxa_camera: ignore -ENOIOCTLCMD from v4l2_subdev_call for s_power

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

 



When the subdevice doesn't provide s_power core ops callback, the
v4l2_subdev_call for s_power returns -ENOIOCTLCMD.  If the subdevice
doesn't have the special handling for its power saving mode, the s_power
isn't required.  So -ENOIOCTLCMD from the v4l2_subdev_call should be
ignored.

Actually the -ENOIOCTLCMD is ignored in this driver's suspend/resume,
but the others treat the -ENOIOCTLCMD as an error.

This prepares a wrapper function to ignore -ENOIOCTLCMD and replaces
all s_power calls with it.

This also adds warning message when s_power() is failed.

Cc: Hans Verkuil <hans.verkuil@xxxxxxxxx>
Cc: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
Cc: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>
Signed-off-by: Akinobu Mita <akinobu.mita@xxxxxxxxx>
---
 drivers/media/platform/pxa_camera.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index c792cb1..4d5a26b 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -2030,6 +2030,22 @@ static int pxac_vidioc_s_input(struct file *file, void *priv, unsigned int i)
 	return 0;
 }
 
+static int pxac_sensor_set_power(struct pxa_camera_dev *pcdev, int on)
+{
+	int ret;
+
+	ret = sensor_call(pcdev, core, s_power, on);
+	if (ret == -ENOIOCTLCMD)
+		ret = 0;
+	if (ret) {
+		dev_warn(pcdev_to_dev(pcdev),
+			 "Failed to put subdevice in %s mode: %d\n",
+			 on ? "normal operation" : "power saving", ret);
+	}
+
+	return ret;
+}
+
 static int pxac_fops_camera_open(struct file *filp)
 {
 	struct pxa_camera_dev *pcdev = video_drvdata(filp);
@@ -2043,7 +2059,7 @@ static int pxac_fops_camera_open(struct file *filp)
 	if (!v4l2_fh_is_singular_file(filp))
 		goto out;
 
-	ret = sensor_call(pcdev, core, s_power, 1);
+	ret = pxac_sensor_set_power(pcdev, 1);
 	if (ret)
 		v4l2_fh_release(filp);
 out:
@@ -2064,7 +2080,7 @@ static int pxac_fops_camera_release(struct file *filp)
 	ret = _vb2_fop_release(filp, NULL);
 
 	if (fh_singular)
-		ret = sensor_call(pcdev, core, s_power, 0);
+		ret = pxac_sensor_set_power(pcdev, 0);
 
 	mutex_unlock(&pcdev->mlock);
 
@@ -2167,7 +2183,7 @@ static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier,
 	pix->pixelformat = pcdev->current_fmt->host_fmt->fourcc;
 	v4l2_fill_mbus_format(mf, pix, pcdev->current_fmt->code);
 
-	err = sensor_call(pcdev, core, s_power, 1);
+	err = pxac_sensor_set_power(pcdev, 1);
 	if (err)
 		goto out;
 
@@ -2194,7 +2210,7 @@ static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier,
 	}
 
 out_sensor_poweroff:
-	err = sensor_call(pcdev, core, s_power, 0);
+	err = pxac_sensor_set_power(pcdev, 0);
 out:
 	mutex_unlock(&pcdev->mlock);
 	return err;
@@ -2249,11 +2265,8 @@ static int pxa_camera_suspend(struct device *dev)
 	pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
 	pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
 
-	if (pcdev->sensor) {
-		ret = sensor_call(pcdev, core, s_power, 0);
-		if (ret == -ENOIOCTLCMD)
-			ret = 0;
-	}
+	if (pcdev->sensor)
+		ret = pxac_sensor_set_power(pcdev, 0);
 
 	return ret;
 }
@@ -2270,9 +2283,7 @@ static int pxa_camera_resume(struct device *dev)
 	__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
 
 	if (pcdev->sensor) {
-		ret = sensor_call(pcdev, core, s_power, 1);
-		if (ret == -ENOIOCTLCMD)
-			ret = 0;
+		ret = pxac_sensor_set_power(pcdev, 1);
 	}
 
 	/* Restart frame capture if active buffer exists */
-- 
2.7.4




[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