Commit e16f5e39 authored by Evgeny Novikov's avatar Evgeny Novikov Committed by Mauro Carvalho Chehab
Browse files

media: atomisp: Fix error handling in probe

There were several issues with handling errors in lm3554_probe():
- Probe did not set the error code when v4l2_ctrl_handler_init() failed.
- It intermixed gotos for handling errors of v4l2_ctrl_handler_init()
  and media_entity_pads_init().
- It did not set the error code for failures of v4l2_ctrl_new_custom().
- Probe did not free resources in case of failures of
  atomisp_register_i2c_module().

The patch fixes all these issues.

Found by Linux Driver Verification project (linuxtesting.org).

Link: https://lore.kernel.org/linux-media/20210810162943.19852-1-novikov@ispras.ru


Signed-off-by: default avatarEvgeny Novikov <novikov@ispras.ru>
Reviewed-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Acked-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent bbe54b1a
Loading
Loading
Loading
Loading
+24 −13
Original line number Diff line number Diff line
@@ -835,7 +835,6 @@ static int lm3554_probe(struct i2c_client *client)
	int err = 0;
	struct lm3554 *flash;
	unsigned int i;
	int ret;

	flash = kzalloc(sizeof(*flash), GFP_KERNEL);
	if (!flash)
@@ -844,7 +843,7 @@ static int lm3554_probe(struct i2c_client *client)
	flash->pdata = lm3554_platform_data_func(client);
	if (IS_ERR(flash->pdata)) {
		err = PTR_ERR(flash->pdata);
		goto fail1;
		goto free_flash;
	}

	v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops);
@@ -852,12 +851,12 @@ static int lm3554_probe(struct i2c_client *client)
	flash->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	flash->mode = ATOMISP_FLASH_MODE_OFF;
	flash->timeout = LM3554_MAX_TIMEOUT / LM3554_TIMEOUT_STEPSIZE - 1;
	ret =
	err =
	    v4l2_ctrl_handler_init(&flash->ctrl_handler,
				   ARRAY_SIZE(lm3554_controls));
	if (ret) {
	if (err) {
		dev_err(&client->dev, "error initialize a ctrl_handler.\n");
		goto fail3;
		goto unregister_subdev;
	}

	for (i = 0; i < ARRAY_SIZE(lm3554_controls); i++)
@@ -866,14 +865,15 @@ static int lm3554_probe(struct i2c_client *client)

	if (flash->ctrl_handler.error) {
		dev_err(&client->dev, "ctrl_handler error.\n");
		goto fail3;
		err = flash->ctrl_handler.error;
		goto free_handler;
	}

	flash->sd.ctrl_handler = &flash->ctrl_handler;
	err = media_entity_pads_init(&flash->sd.entity, 0, NULL);
	if (err) {
		dev_err(&client->dev, "error initialize a media entity.\n");
		goto fail2;
		goto free_handler;
	}

	flash->sd.entity.function = MEDIA_ENT_F_FLASH;
@@ -884,16 +884,27 @@ static int lm3554_probe(struct i2c_client *client)

	err = lm3554_gpio_init(client);
	if (err) {
		dev_err(&client->dev, "gpio request/direction_output fail");
		goto fail3;
		dev_err(&client->dev, "gpio request/direction_output fail.\n");
		goto cleanup_media;
	}

	err = atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
	if (err) {
		dev_err(&client->dev, "fail to register atomisp i2c module.\n");
		goto uninit_gpio;
	}
	return atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
fail3:

	return 0;

uninit_gpio:
	lm3554_gpio_uninit(client);
cleanup_media:
	media_entity_cleanup(&flash->sd.entity);
free_handler:
	v4l2_ctrl_handler_free(&flash->ctrl_handler);
fail2:
unregister_subdev:
	v4l2_device_unregister_subdev(&flash->sd);
fail1:
free_flash:
	kfree(flash);

	return err;