diff options
| author | Akinobu Mita <akinobu.mita@gmail.com> | 2018-06-03 10:14:25 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-06-05 09:50:20 -0400 |
| commit | 8cbc3a856fc6acee31f9820a566a9625776b68ee (patch) | |
| tree | 1ebb94a183bbed7d00e7b0be286f1ca25e1279de /drivers/media | |
| parent | 2b787b66bcb03ec3bd97e950464e0452f459e2ca (diff) | |
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>
Diffstat (limited to 'drivers/media')
| -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) | |||
| 2030 | return 0; | 2030 | return 0; |
| 2031 | } | 2031 | } |
| 2032 | 2032 | ||
| 2033 | static int pxac_sensor_set_power(struct pxa_camera_dev *pcdev, int on) | ||
| 2034 | { | ||
| 2035 | int ret; | ||
| 2036 | |||
| 2037 | ret = sensor_call(pcdev, core, s_power, on); | ||
| 2038 | if (ret == -ENOIOCTLCMD) | ||
| 2039 | ret = 0; | ||
| 2040 | if (ret) { | ||
| 2041 | dev_warn(pcdev_to_dev(pcdev), | ||
| 2042 | "Failed to put subdevice in %s mode: %d\n", | ||
| 2043 | on ? "normal operation" : "power saving", ret); | ||
| 2044 | } | ||
| 2045 | |||
| 2046 | return ret; | ||
| 2047 | } | ||
| 2048 | |||
| 2033 | static int pxac_fops_camera_open(struct file *filp) | 2049 | static int pxac_fops_camera_open(struct file *filp) |
| 2034 | { | 2050 | { |
| 2035 | struct pxa_camera_dev *pcdev = video_drvdata(filp); | 2051 | struct pxa_camera_dev *pcdev = video_drvdata(filp); |
| @@ -2043,7 +2059,7 @@ static int pxac_fops_camera_open(struct file *filp) | |||
| 2043 | if (!v4l2_fh_is_singular_file(filp)) | 2059 | if (!v4l2_fh_is_singular_file(filp)) |
| 2044 | goto out; | 2060 | goto out; |
| 2045 | 2061 | ||
| 2046 | ret = sensor_call(pcdev, core, s_power, 1); | 2062 | ret = pxac_sensor_set_power(pcdev, 1); |
| 2047 | if (ret) | 2063 | if (ret) |
| 2048 | v4l2_fh_release(filp); | 2064 | v4l2_fh_release(filp); |
| 2049 | out: | 2065 | out: |
| @@ -2064,7 +2080,7 @@ static int pxac_fops_camera_release(struct file *filp) | |||
| 2064 | ret = _vb2_fop_release(filp, NULL); | 2080 | ret = _vb2_fop_release(filp, NULL); |
| 2065 | 2081 | ||
| 2066 | if (fh_singular) | 2082 | if (fh_singular) |
| 2067 | ret = sensor_call(pcdev, core, s_power, 0); | 2083 | ret = pxac_sensor_set_power(pcdev, 0); |
| 2068 | 2084 | ||
| 2069 | mutex_unlock(&pcdev->mlock); | 2085 | mutex_unlock(&pcdev->mlock); |
| 2070 | 2086 | ||
| @@ -2167,7 +2183,7 @@ static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier, | |||
| 2167 | pix->pixelformat = pcdev->current_fmt->host_fmt->fourcc; | 2183 | pix->pixelformat = pcdev->current_fmt->host_fmt->fourcc; |
| 2168 | v4l2_fill_mbus_format(mf, pix, pcdev->current_fmt->code); | 2184 | v4l2_fill_mbus_format(mf, pix, pcdev->current_fmt->code); |
| 2169 | 2185 | ||
| 2170 | err = sensor_call(pcdev, core, s_power, 1); | 2186 | err = pxac_sensor_set_power(pcdev, 1); |
| 2171 | if (err) | 2187 | if (err) |
| 2172 | goto out; | 2188 | goto out; |
| 2173 | 2189 | ||
| @@ -2194,7 +2210,7 @@ static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier, | |||
| 2194 | } | 2210 | } |
| 2195 | 2211 | ||
| 2196 | out_sensor_poweroff: | 2212 | out_sensor_poweroff: |
| 2197 | err = sensor_call(pcdev, core, s_power, 0); | 2213 | err = pxac_sensor_set_power(pcdev, 0); |
| 2198 | out: | 2214 | out: |
| 2199 | mutex_unlock(&pcdev->mlock); | 2215 | mutex_unlock(&pcdev->mlock); |
| 2200 | return err; | 2216 | return err; |
| @@ -2249,11 +2265,8 @@ static int pxa_camera_suspend(struct device *dev) | |||
| 2249 | pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3); | 2265 | pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3); |
| 2250 | pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4); | 2266 | pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4); |
| 2251 | 2267 | ||
| 2252 | if (pcdev->sensor) { | 2268 | if (pcdev->sensor) |
| 2253 | ret = sensor_call(pcdev, core, s_power, 0); | 2269 | ret = pxac_sensor_set_power(pcdev, 0); |
| 2254 | if (ret == -ENOIOCTLCMD) | ||
| 2255 | ret = 0; | ||
| 2256 | } | ||
| 2257 | 2270 | ||
| 2258 | return ret; | 2271 | return ret; |
| 2259 | } | 2272 | } |
| @@ -2270,9 +2283,7 @@ static int pxa_camera_resume(struct device *dev) | |||
| 2270 | __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4); | 2283 | __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4); |
| 2271 | 2284 | ||
| 2272 | if (pcdev->sensor) { | 2285 | if (pcdev->sensor) { |
| 2273 | ret = sensor_call(pcdev, core, s_power, 1); | 2286 | ret = pxac_sensor_set_power(pcdev, 1); |
| 2274 | if (ret == -ENOIOCTLCMD) | ||
| 2275 | ret = 0; | ||
| 2276 | } | 2287 | } |
| 2277 | 2288 | ||
| 2278 | /* Restart frame capture if active buffer exists */ | 2289 | /* Restart frame capture if active buffer exists */ |
