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