media: atomisp: Fix error handling in probe
[ Upstream commit e16f5e39acd6d10cc63ae39bc0a77188ed828f22 ] 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: Evgeny Novikov <novikov@ispras.ru> Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com> Acked-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>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
f4c652bd35
commit
309ea2248d
@@ -836,7 +836,6 @@ static int lm3554_probe(struct i2c_client *client)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
struct lm3554 *flash;
|
struct lm3554 *flash;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
|
||||||
|
|
||||||
flash = kzalloc(sizeof(*flash), GFP_KERNEL);
|
flash = kzalloc(sizeof(*flash), GFP_KERNEL);
|
||||||
if (!flash)
|
if (!flash)
|
||||||
@@ -845,7 +844,7 @@ static int lm3554_probe(struct i2c_client *client)
|
|||||||
flash->pdata = lm3554_platform_data_func(client);
|
flash->pdata = lm3554_platform_data_func(client);
|
||||||
if (IS_ERR(flash->pdata)) {
|
if (IS_ERR(flash->pdata)) {
|
||||||
err = PTR_ERR(flash->pdata);
|
err = PTR_ERR(flash->pdata);
|
||||||
goto fail1;
|
goto free_flash;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops);
|
v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops);
|
||||||
@@ -853,12 +852,12 @@ static int lm3554_probe(struct i2c_client *client)
|
|||||||
flash->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
flash->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||||
flash->mode = ATOMISP_FLASH_MODE_OFF;
|
flash->mode = ATOMISP_FLASH_MODE_OFF;
|
||||||
flash->timeout = LM3554_MAX_TIMEOUT / LM3554_TIMEOUT_STEPSIZE - 1;
|
flash->timeout = LM3554_MAX_TIMEOUT / LM3554_TIMEOUT_STEPSIZE - 1;
|
||||||
ret =
|
err =
|
||||||
v4l2_ctrl_handler_init(&flash->ctrl_handler,
|
v4l2_ctrl_handler_init(&flash->ctrl_handler,
|
||||||
ARRAY_SIZE(lm3554_controls));
|
ARRAY_SIZE(lm3554_controls));
|
||||||
if (ret) {
|
if (err) {
|
||||||
dev_err(&client->dev, "error initialize a ctrl_handler.\n");
|
dev_err(&client->dev, "error initialize a ctrl_handler.\n");
|
||||||
goto fail3;
|
goto unregister_subdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(lm3554_controls); i++)
|
for (i = 0; i < ARRAY_SIZE(lm3554_controls); i++)
|
||||||
@@ -867,14 +866,15 @@ static int lm3554_probe(struct i2c_client *client)
|
|||||||
|
|
||||||
if (flash->ctrl_handler.error) {
|
if (flash->ctrl_handler.error) {
|
||||||
dev_err(&client->dev, "ctrl_handler error.\n");
|
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;
|
flash->sd.ctrl_handler = &flash->ctrl_handler;
|
||||||
err = media_entity_pads_init(&flash->sd.entity, 0, NULL);
|
err = media_entity_pads_init(&flash->sd.entity, 0, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&client->dev, "error initialize a media entity.\n");
|
dev_err(&client->dev, "error initialize a media entity.\n");
|
||||||
goto fail2;
|
goto free_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
flash->sd.entity.function = MEDIA_ENT_F_FLASH;
|
flash->sd.entity.function = MEDIA_ENT_F_FLASH;
|
||||||
@@ -885,16 +885,27 @@ static int lm3554_probe(struct i2c_client *client)
|
|||||||
|
|
||||||
err = lm3554_gpio_init(client);
|
err = lm3554_gpio_init(client);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&client->dev, "gpio request/direction_output fail");
|
dev_err(&client->dev, "gpio request/direction_output fail.\n");
|
||||||
goto fail3;
|
goto cleanup_media;
|
||||||
}
|
}
|
||||||
return atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
|
|
||||||
fail3:
|
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 0;
|
||||||
|
|
||||||
|
uninit_gpio:
|
||||||
|
lm3554_gpio_uninit(client);
|
||||||
|
cleanup_media:
|
||||||
media_entity_cleanup(&flash->sd.entity);
|
media_entity_cleanup(&flash->sd.entity);
|
||||||
|
free_handler:
|
||||||
v4l2_ctrl_handler_free(&flash->ctrl_handler);
|
v4l2_ctrl_handler_free(&flash->ctrl_handler);
|
||||||
fail2:
|
unregister_subdev:
|
||||||
v4l2_device_unregister_subdev(&flash->sd);
|
v4l2_device_unregister_subdev(&flash->sd);
|
||||||
fail1:
|
free_flash:
|
||||||
kfree(flash);
|
kfree(flash);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
Reference in New Issue
Block a user