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>
This commit is contained in:
Akinobu Mita 2018-06-03 10:14:25 -04:00 committed by Mauro Carvalho Chehab
parent 2b787b66bc
commit 8cbc3a856f
1 changed files with 23 additions and 12 deletions

View File

@ -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 */