| From 779f906f53204691c3c45b52d788bf764835f736 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 11 Mar 2021 10:52:05 +0100 |
| Subject: media: i2c: imx219: Balance runtime PM use-count |
| |
| From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> |
| |
| [ Upstream commit dd90caa0111e178b52b21e56364bc2244a3973b3 ] |
| |
| Move incrementing/decrementing runtime PM count to |
| imx219_start_streaming()/imx219_stop_streaming() functions respectively. |
| |
| This fixes an issue of unbalanced runtime PM count in resume callback |
| error path where streaming is stopped and runtime PM count is left |
| unbalanced. |
| |
| Fixes: 1283b3b8f82b9 ("media: i2c: Add driver for Sony IMX219 sensor") |
| Reported-by: Pavel Machek <pavel@denx.de> |
| Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> |
| Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
| Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/media/i2c/imx219.c | 32 +++++++++++++++++--------------- |
| 1 file changed, 17 insertions(+), 15 deletions(-) |
| |
| diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c |
| index 82756cbfbaac..49ba39418360 100644 |
| --- a/drivers/media/i2c/imx219.c |
| +++ b/drivers/media/i2c/imx219.c |
| @@ -1035,37 +1035,47 @@ static int imx219_start_streaming(struct imx219 *imx219) |
| const struct imx219_reg_list *reg_list; |
| int ret; |
| |
| + ret = pm_runtime_get_sync(&client->dev); |
| + if (ret < 0) { |
| + pm_runtime_put_noidle(&client->dev); |
| + return ret; |
| + } |
| + |
| /* Apply default values of current mode */ |
| reg_list = &imx219->mode->reg_list; |
| ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); |
| if (ret) { |
| dev_err(&client->dev, "%s failed to set mode\n", __func__); |
| - return ret; |
| + goto err_rpm_put; |
| } |
| |
| ret = imx219_set_framefmt(imx219); |
| if (ret) { |
| dev_err(&client->dev, "%s failed to set frame format: %d\n", |
| __func__, ret); |
| - return ret; |
| + goto err_rpm_put; |
| } |
| |
| /* Apply customized values from user */ |
| ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); |
| if (ret) |
| - return ret; |
| + goto err_rpm_put; |
| |
| /* set stream on register */ |
| ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, |
| IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); |
| if (ret) |
| - return ret; |
| + goto err_rpm_put; |
| |
| /* vflip and hflip cannot change during streaming */ |
| __v4l2_ctrl_grab(imx219->vflip, true); |
| __v4l2_ctrl_grab(imx219->hflip, true); |
| |
| return 0; |
| + |
| +err_rpm_put: |
| + pm_runtime_put(&client->dev); |
| + return ret; |
| } |
| |
| static void imx219_stop_streaming(struct imx219 *imx219) |
| @@ -1081,12 +1091,13 @@ static void imx219_stop_streaming(struct imx219 *imx219) |
| |
| __v4l2_ctrl_grab(imx219->vflip, false); |
| __v4l2_ctrl_grab(imx219->hflip, false); |
| + |
| + pm_runtime_put(&client->dev); |
| } |
| |
| static int imx219_set_stream(struct v4l2_subdev *sd, int enable) |
| { |
| struct imx219 *imx219 = to_imx219(sd); |
| - struct i2c_client *client = v4l2_get_subdevdata(sd); |
| int ret = 0; |
| |
| mutex_lock(&imx219->mutex); |
| @@ -1096,22 +1107,15 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) |
| } |
| |
| if (enable) { |
| - ret = pm_runtime_get_sync(&client->dev); |
| - if (ret < 0) { |
| - pm_runtime_put_noidle(&client->dev); |
| - goto err_unlock; |
| - } |
| - |
| /* |
| * Apply default & customized values |
| * and then start streaming. |
| */ |
| ret = imx219_start_streaming(imx219); |
| if (ret) |
| - goto err_rpm_put; |
| + goto err_unlock; |
| } else { |
| imx219_stop_streaming(imx219); |
| - pm_runtime_put(&client->dev); |
| } |
| |
| imx219->streaming = enable; |
| @@ -1120,8 +1124,6 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) |
| |
| return ret; |
| |
| -err_rpm_put: |
| - pm_runtime_put(&client->dev); |
| err_unlock: |
| mutex_unlock(&imx219->mutex); |
| |
| -- |
| 2.30.2 |
| |