Commit da3a1858 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

media: i2c: ccs-core: fix pm_runtime_get_sync() usage count



The pm_runtime_get_sync() internally increments the
dev->power.usage_count without decrementing it, even on errors.

There is a bug at ccs_pm_get_init(): when this function returns
an error, the stream is not started, and RPM usage_count
should not be incremented. However, if the calls to
v4l2_ctrl_handler_setup() return errors, it will be kept
incremented.

At ccs_suspend() the best is to replace it by the new
pm_runtime_resume_and_get(), introduced by:
commit dd8088d5 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
in order to properly decrement the usage counter automatically,
in the case of errors.

Fixes: 96e3a6b9 ("media: smiapp: Avoid maintaining power state information")
Cc: stable@vger.kernel.org
Acked-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 6005a8e9
Loading
Loading
Loading
Loading
+22 −10
Original line number Diff line number Diff line
@@ -1880,21 +1880,33 @@ static int ccs_pm_get_init(struct ccs_sensor *sensor)
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
	int rval;

	/*
	 * It can't use pm_runtime_resume_and_get() here, as the driver
	 * relies at the returned value to detect if the device was already
	 * active or not.
	 */
	rval = pm_runtime_get_sync(&client->dev);
	if (rval < 0) {
		pm_runtime_put_noidle(&client->dev);
	if (rval < 0)
		goto error;

		return rval;
	} else if (!rval) {
		rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->
					       ctrl_handler);
	/* Device was already active, so don't set controls */
	if (rval == 1)
		return 0;

	/* Restore V4L2 controls to the previously suspended device */
	rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler);
	if (rval)
			return rval;
		goto error;

		return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
	}
	rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
	if (rval)
		goto error;

	/* Keep PM runtime usage_count incremented on success */
	return 0;
error:
	pm_runtime_put(&client->dev);
	return rval;
}

static int ccs_set_stream(struct v4l2_subdev *subdev, int enable)