summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2018-06-03 17:14:25 +0300
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-06-05 16:50:20 +0300
commit8cbc3a856fc6acee31f9820a566a9625776b68ee (patch)
tree1ebb94a183bbed7d00e7b0be286f1ca25e1279de
parent2b787b66bcb03ec3bd97e950464e0452f459e2ca (diff)
downloadlinux-8cbc3a856fc6acee31f9820a566a9625776b68ee.tar.xz
media: pxa_camera: ignore -ENOIOCTLCMD from v4l2_subdev_call for s_power
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: Sakari Ailus <sakari.ailus@linux.intel.com> 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>
-rw-r--r--drivers/media/platform/pxa_camera.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index c792cb178a84..4d5a26b4cdda 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 */