On Wed May 6 09:48:43 2026 +0300, Svyatoslav Ryhel wrote:
> 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 <[email protected]>
> Signed-off-by: Sakari Ailus <[email protected]>

Patch committed.

Thanks,
Sakari Ailus

 drivers/media/i2c/lm3560.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

---

diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index f4cc844f4e3c..edfb07587cab 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -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_subdev_init(flash, LM3560_LED0, "lm3560-led0");
+       rval = lm3560_init_device(flash);
        if (rval < 0)
                return rval;
 
-       rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1");
+       rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0");
        if (rval < 0)
                return rval;
 
-       rval = lm3560_init_device(flash);
-       if (rval < 0)
+       rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1");
+       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[] = {
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to