[PATCH 09/21] leds: sgm3140: Cancel powerdown work via devres after LED unregistration
From: Lee Jones
Date: Wed Oct 21 2026 - 08:43:36 EST
Because devm_led_classdev_flash_register_ext() unregisters the flash LED
device via devres after sgm3140_remove() returns, cancelling
powerdown_work manually in sgm3140_remove() leaves a window where a
concurrent sysfs write to flash_strobe can re-arm powerdown_work before
the LED class device is unregistered and priv is freed. A similar
window exists in sgm3140_probe() if v4l2_flash_init() fails after the
LED class device has been registered.
Initialise powerdown_work with devm_delayed_work_autocancel() before
calling devm_led_classdev_flash_register_ext() so that devres cancels
the work after unregistering the LED class device and before releasing
the regulator, GPIOs, and driver data.
Fixes: cef8ec8cbd21 ("leds: add sgm3140 driver")
Closes: https://sashiko.dev/#/bug/linux-81468d52-b80d-46b5-b1b4-29c35e9acb21
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
---
drivers/leds/flash/leds-sgm3140.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/leds/flash/leds-sgm3140.c b/drivers/leds/flash/leds-sgm3140.c
index 478573da1d61..4e21144900c9 100644
--- a/drivers/leds/flash/leds-sgm3140.c
+++ b/drivers/leds/flash/leds-sgm3140.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2020 Luca Weiss <luca@xxxxxxxxx>
+#include <linux/devm-helpers.h>
#include <linux/gpio/consumer.h>
#include <linux/led-class-flash.h>
#include <linux/module.h>
@@ -237,7 +238,10 @@ static int sgm3140_probe(struct platform_device *pdev)
*/
priv->timeout = min(priv->max_timeout, FLASH_TIMEOUT_DEFAULT);
- INIT_DELAYED_WORK(&priv->powerdown_work, sgm3140_powerdown_work);
+ ret = devm_delayed_work_autocancel(&pdev->dev, &priv->powerdown_work,
+ sgm3140_powerdown_work);
+ if (ret)
+ goto err;
fled_cdev = &priv->fled_cdev;
led_cdev = &fled_cdev->led_cdev;
@@ -286,8 +290,6 @@ static void sgm3140_remove(struct platform_device *pdev)
{
struct sgm3140 *priv = platform_get_drvdata(pdev);
- cancel_delayed_work_sync(&priv->powerdown_work);
-
v4l2_flash_release(priv->v4l2_flash);
}
--
2.56.0.218.g1ec904b173-goog