[PATCH 1/6] backlight: lm3630a: Request PWM device before registering backlight
From: Lee Jones
Date: Wed Nov 04 2026 - 14:30:55 EST
lm3630a_probe() currently registers the backlight devices via
lm3630a_backlight_register() before acquiring and initialising the PWM
device via devm_pwm_get() and pwm_init_state().
This creates two issues when PWM control is enabled:
1. Exposing the backlight sysfs attributes before pchip->pwmd is
initialised leaves a window during probe where a userspace brightness
update calls lm3630a_pwm_ctrl() with pchip->pwmd still NULL (or set
to an ERR_PTR() if devm_pwm_get() fails while devres tears down the
backlight device).
2. Because devres releases resources in reverse registration order on
driver unbind, the PWM device is released before the backlight
devices are unregistered, allowing a sysfs brightness write during
unbind to invoke lm3630a_pwm_ctrl() on a freed PWM device.
Acquire and initialise the PWM device before registering the backlight
devices so that pchip->pwmd is valid throughout the lifetime of the
backlight registration.
Fixes: 28e64a68a2ef ("backlight: lm3630: apply chip revision")
Closes: https://sashiko.dev/#/bug/linux-ba01ed63-0b5a-4b3d-94c5-e6989857d77c
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
---
drivers/video/backlight/lm3630a_bl.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
index 8ef8163c7fef..9061355ef8ed 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -549,12 +549,6 @@ static int lm3630a_probe(struct i2c_client *client)
dev_err(&client->dev, "fail : init chip\n");
return rval;
}
- /* backlight register */
- rval = lm3630a_backlight_register(pchip);
- if (rval < 0) {
- dev_err(&client->dev, "fail : backlight register.\n");
- return rval;
- }
/* pwm */
if (pdata->pwm_ctrl != LM3630A_PWM_DISABLE) {
pchip->pwmd = devm_pwm_get(pchip->dev, "lm3630a-pwm");
@@ -564,6 +558,12 @@ static int lm3630a_probe(struct i2c_client *client)
pwm_init_state(pchip->pwmd, &pchip->pwmd_state);
}
+ /* backlight register */
+ rval = lm3630a_backlight_register(pchip);
+ if (rval < 0) {
+ dev_err(&client->dev, "fail : backlight register.\n");
+ return rval;
+ }
/* interrupt enable : irq 0 is not allowed */
pchip->irq = client->irq;
--
2.56.0.385.gac671c819a-goog