mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 02:31:27 +02:00
media: i2c: lm3560: Fix v4l2 subdev registration
The existing driver does not call media subdev registration, making it invisible to the media framework. Since the LM3560 supports two independent LEDs, register each LED as a separate media entity. Because registering LEDs before device initialization may cause access attempts before the hardware is ready, lm3560_init_device has been moved before the subdevice initializations. An additional helper, lm3560_subdev_cleanup, was added to release LED0 if the initialization of LED1 fails, and to deregister both LEDs in the remove function. Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
This commit is contained in:
parent
621e4f762e
commit
38547c3d87
|
|
@ -364,8 +364,15 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
|
|||
goto err_out;
|
||||
flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH;
|
||||
|
||||
return rval;
|
||||
rval = v4l2_async_register_subdev(&flash->subdev_led[led_no]);
|
||||
if (rval < 0) {
|
||||
dev_err(flash->dev, "failed to register V4L2 subdev");
|
||||
goto error_out_media;
|
||||
}
|
||||
|
||||
return rval;
|
||||
error_out_media:
|
||||
media_entity_cleanup(&flash->subdev_led[led_no].entity);
|
||||
err_out:
|
||||
v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]);
|
||||
return rval;
|
||||
|
|
@ -391,6 +398,14 @@ static int lm3560_init_device(struct lm3560_flash *flash)
|
|||
return rval;
|
||||
}
|
||||
|
||||
static void lm3560_subdev_cleanup(struct lm3560_flash *flash,
|
||||
enum lm3560_led_id led_no)
|
||||
{
|
||||
v4l2_async_unregister_subdev(&flash->subdev_led[led_no]);
|
||||
v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]);
|
||||
media_entity_cleanup(&flash->subdev_led[led_no].entity);
|
||||
}
|
||||
|
||||
static int lm3560_probe(struct i2c_client *client)
|
||||
{
|
||||
struct lm3560_flash *flash;
|
||||
|
|
@ -425,17 +440,19 @@ static int lm3560_probe(struct i2c_client *client)
|
|||
flash->dev = &client->dev;
|
||||
mutex_init(&flash->lock);
|
||||
|
||||
rval = lm3560_init_device(flash);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0");
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1");
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
rval = lm3560_init_device(flash);
|
||||
if (rval < 0)
|
||||
if (rval < 0) {
|
||||
lm3560_subdev_cleanup(flash, LM3560_LED0);
|
||||
return rval;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, flash);
|
||||
|
||||
|
|
@ -447,11 +464,8 @@ static void lm3560_remove(struct i2c_client *client)
|
|||
struct lm3560_flash *flash = i2c_get_clientdata(client);
|
||||
unsigned int i;
|
||||
|
||||
for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {
|
||||
v4l2_device_unregister_subdev(&flash->subdev_led[i]);
|
||||
v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
|
||||
media_entity_cleanup(&flash->subdev_led[i].entity);
|
||||
}
|
||||
for (i = LM3560_LED0; i < LM3560_LED_MAX; i++)
|
||||
lm3560_subdev_cleanup(flash, i);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lm3560_id_table[] = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user