diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2018-06-03 17:14:25 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-06-05 16:50:20 +0300 |
commit | 8cbc3a856fc6acee31f9820a566a9625776b68ee (patch) | |
tree | 1ebb94a183bbed7d00e7b0be286f1ca25e1279de | |
parent | 2b787b66bcb03ec3bd97e950464e0452f459e2ca (diff) | |
download | linux-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.c | 35 |
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 */ |