Commit f738cb62 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

media: rkisp1: resizer: Fix and simplify (un)registration



The rkisp1_rsz_register() and rkisp1_rsz_unregister() functions don't
destroy the mutex (in the error path for the former). Fix this, simplify
error handling at registration time as media_entity_cleanup() can be
called on an uninitialized entity, and make rkisp1_rsz_unregister() and
rkisp1_resizer_devs_unregister() safe to be called on an unregistered
resizer subdev to prepare for simplification of error handling at probe
time.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarDafna Hirschfeld <dafna@fastmail.com>
Reviewed-by: default avatarRicardo Ribalda <ribalda@chromium.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 48d77568
Loading
Loading
Loading
Loading
+17 −17
Original line number Diff line number Diff line
@@ -782,8 +782,12 @@ static const struct v4l2_subdev_ops rkisp1_rsz_ops = {

static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
{
	if (!rsz->rkisp1)
		return;

	v4l2_device_unregister_subdev(&rsz->sd);
	media_entity_cleanup(&rsz->sd.entity);
	mutex_destroy(&rsz->ops_lock);
}

static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
@@ -821,47 +825,43 @@ static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
	mutex_init(&rsz->ops_lock);
	ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
	if (ret)
		return ret;
		goto error;

	ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
	if (ret) {
		dev_err(sd->dev, "Failed to register resizer subdev\n");
		goto err_cleanup_media_entity;
		goto error;
	}

	rkisp1_rsz_init_config(sd, &state);
	return 0;

err_cleanup_media_entity:
error:
	media_entity_cleanup(&sd->entity);

	mutex_destroy(&rsz->ops_lock);
	return ret;
}

int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
{
	struct rkisp1_resizer *rsz;
	unsigned int i, j;
	unsigned int i;
	int ret;

	for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
		rsz = &rkisp1->resizer_devs[i];
		struct rkisp1_resizer *rsz = &rkisp1->resizer_devs[i];

		rsz->rkisp1 = rkisp1;
		rsz->id = i;

		ret = rkisp1_rsz_register(rsz);
		if (ret)
			goto err_unreg_resizer_devs;
		if (ret) {
			rsz->rkisp1 = NULL;
			rkisp1_resizer_devs_unregister(rkisp1);
			return ret;
		}

	return 0;

err_unreg_resizer_devs:
	for (j = 0; j < i; j++) {
		rsz = &rkisp1->resizer_devs[j];
		rkisp1_rsz_unregister(rsz);
	}

	return ret;
	return 0;
}

void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)