[PATCH 2/6] backlight: aat2870: Initialise driver data before registering backlight
From: Lee Jones
Date: Wed Nov 04 2026 - 15:30:18 EST
aat2870_bl_probe() currently registers the backlight device via
devm_backlight_device_register() before initialising its private driver
data (aat2870_bl->pdev, channels, and max_current) and backlight
properties (max_brightness, power, and brightness).
Because devm_backlight_device_register() immediately exposes the
backlight sysfs interface to userspace, a concurrent sysfs write to
attributes such as brightness invokes aat2870_bl_update_status() while
aat2870_bl->pdev is still NULL, causing a NULL pointer dereference. In
addition, aat2870_brightness() reads the backlight_device pointer from
aat2870_bl->bd (which is only assigned after registration returns)
rather than using the backlight_device pointer passed into
aat2870_bl_update_status().
Populate the driver data and backlight_properties structure prior to
calling devm_backlight_device_register(), and pass the backlight_device
pointer directly to aat2870_brightness().
Fixes: 4b0d711be39f ("backlight: Add AAT2870 backlight driver")
Closes: https://sashiko.dev/#/bug/linux-9a61532b-5d7a-467d-b3d1-d6420978c8f3
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
---
drivers/video/backlight/aat2870_bl.c | 43 ++++++++++++++--------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
index 8b790df1e842..53eaa3e1e7a3 100644
--- a/drivers/video/backlight/aat2870_bl.c
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -24,10 +24,10 @@ struct aat2870_bl_driver_data {
int brightness; /* current brightness */
};
-static inline int aat2870_brightness(struct aat2870_bl_driver_data *aat2870_bl,
+static inline int aat2870_brightness(struct backlight_device *bd,
int brightness)
{
- struct backlight_device *bd = aat2870_bl->bd;
+ struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd);
int val;
val = brightness * (aat2870_bl->max_current - 1);
@@ -70,7 +70,7 @@ static int aat2870_bl_update_status(struct backlight_device *bd)
bd->props.brightness, bd->props.power, bd->props.state);
ret = aat2870->write(aat2870, AAT2870_BLM,
- (u8)aat2870_brightness(aat2870_bl, brightness));
+ (u8)aat2870_brightness(bd, brightness));
if (ret < 0)
return ret;
@@ -122,24 +122,9 @@ static int aat2870_bl_probe(struct platform_device *pdev)
goto out;
}
- memset(&props, 0, sizeof(struct backlight_properties));
-
- props.type = BACKLIGHT_RAW;
- bd = devm_backlight_device_register(&pdev->dev, "aat2870-backlight",
- &pdev->dev, aat2870_bl, &aat2870_bl_ops,
- &props);
- if (IS_ERR(bd)) {
- dev_err(&pdev->dev,
- "Failed allocate memory for backlight device\n");
- ret = PTR_ERR(bd);
- goto out;
- }
-
aat2870_bl->pdev = pdev;
platform_set_drvdata(pdev, aat2870_bl);
- aat2870_bl->bd = bd;
-
if (pdata->channels > 0)
aat2870_bl->channels = pdata->channels;
else
@@ -150,14 +135,28 @@ static int aat2870_bl_probe(struct platform_device *pdev)
else
aat2870_bl->max_current = AAT2870_CURRENT_27_9;
+ memset(&props, 0, sizeof(struct backlight_properties));
+
+ props.type = BACKLIGHT_RAW;
if (pdata->max_brightness > 0)
- bd->props.max_brightness = pdata->max_brightness;
+ props.max_brightness = pdata->max_brightness;
else
- bd->props.max_brightness = 255;
+ props.max_brightness = 255;
aat2870_bl->brightness = 0;
- bd->props.power = BACKLIGHT_POWER_ON;
- bd->props.brightness = bd->props.max_brightness;
+ props.power = BACKLIGHT_POWER_ON;
+ props.brightness = props.max_brightness;
+
+ bd = devm_backlight_device_register(&pdev->dev, "aat2870-backlight",
+ &pdev->dev, aat2870_bl,
+ &aat2870_bl_ops, &props);
+ if (IS_ERR(bd)) {
+ dev_err(&pdev->dev,
+ "Failed allocate memory for backlight device\n");
+ ret = PTR_ERR(bd);
+ goto out;
+ }
+ aat2870_bl->bd = bd;
ret = aat2870_bl_update_status(bd);
if (ret < 0) {
--
2.56.0.385.gac671c819a-goog