All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "David Heidelberg" <david@ixit.cz>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] backlight: qcom-wled: Fix unbalanced OVP IRQ enable at probe
Date: Tue, 08 Sep 2026 21:09:46 +0000	[thread overview]
Message-ID: <20260908210947.099E21F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260908-qcom-wled-backlight-v1-1-c4dd4eabda07@ixit.cz>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:

New issues:
- [High] If default-brightness is 0, the OVP IRQ is incorrectly disabled while the hardware module remains active, and the module cannot be subsequently disabled.

Pre-existing issues:
- [High] Missing platform_set_drvdata() in probe causes a guaranteed NULL pointer dereference in wled_remove().
- [High] wled_remove() calls disable_irq() with negative or uninitialized IRQ values if the IRQs failed to map during probe.
- [High] Tearing down synchronization primitives in wled_remove() before the devm-managed backlight is unregistered creates a use-after-free window.
- [High] WLED3 devices lack the wled_auto_detection_required function handler, leading to a NULL pointer dereference if the OVP IRQ fires.
- [High] The short IRQ handler unconditionally re-enables the hardware module, overriding software intentions.
--

commit 5bacd29d54de18ff6f2680d6c09d873e1a8a3c3a
Author: David Heidelberg <david@ixit.cz>

    backlight: qcom-wled: Fix unbalanced OVP IRQ enable at probe

This commit fixes an issue where the OVP IRQ was unbalanced at probe. It reads
the hardware module enable state to initialize the software brightness level,
and keys the OVP IRQ enable off this software state rather than the hardware
state to avoid mismatches.

> diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
> index 650dd95f06ef5..344b8cad90105 100644
> --- a/drivers/video/backlight/qcom-wled.c
> +++ b/drivers/video/backlight/qcom-wled.c
> @@ -1627,7 +1627,6 @@ static int wled_configure_ovp_irq(struct wled *wled,
>  				  struct platform_device *pdev)
>  {
>  	int rc;
> -	u32 val;
>  
>  	wled->ovp_irq = platform_get_irq_byname(pdev, "ovp");
>  	if (wled->ovp_irq < 0) {

[Severity: High]
This is a pre-existing issue, but if platform_get_irq_byname() fails and
returns a negative error code, it is left in wled->ovp_irq without being
reset to 0.

Could this cause a regression during module removal?

drivers/video/backlight/qcom-wled.c:wled_remove() {
...
    disable_irq(wled->ovp_irq);
...
}

It appears wled_remove() calls disable_irq() unconditionally, which would
result in an out-of-bounds IRQ descriptor lookup or inadvertently disabling a
system IRQ if wled->ovp_irq is negative.

[ ... ]
> @@ -1643,13 +1642,8 @@ static int wled_configure_ovp_irq(struct wled *wled,
>  		return 0;
>  	}
>  
> -	rc = regmap_read(wled->regmap, wled->ctrl_addr +
> -			 WLED3_CTRL_REG_MOD_EN, &val);
> -	if (rc < 0)
> -		return rc;
> -
> -	/* Keep OVP irq disabled until module is enabled */
> -	if (!(val & WLED3_CTRL_REG_MOD_EN_MASK))
> +	/* Keep the OVP irq disabled until the module is enabled */
> +	if (!wled->brightness)
>  		disable_irq(wled->ovp_irq);

[Severity: High]
If default-brightness is 0, wled->brightness will be seeded with 0 later in
wled_probe(). Will this incorrectly disable the OVP IRQ while the hardware
module remains active?

If the bootloader leaves the backlight ON, but default-brightness in the device
tree is 0, checking !wled->brightness instead of the hardware MOD_EN state
disables the OVP IRQ while hardware is still ON.

Additionally, a user space request to set brightness to 0 evaluates
!!0 != !!0 as false, silently ignoring the request and leaving the hardware
permanently ON without OVP protection.

[ ... ]
> @@ -1734,6 +1729,24 @@ static int wled_probe(struct platform_device *pdev)
>  
>  	INIT_DELAYED_WORK(&wled->ovp_work, wled_ovp_work);
>  
> +	val = WLED_DEFAULT_BRIGHTNESS;
> +	of_property_read_u32(pdev->dev.of_node, "default-brightness", &val);
> +
> +	/*
> +	 * The module may already be enabled, either by a bootloader that left
> +	 * the backlight lit or by the setup above. Record that, so that the
> +	 * first brightness update does not enable an already enabled module,
> +	 * and so that the OVP irq is armed from probe rather than from that
> +	 * first update.
> +	 */
> +	rc = regmap_read(wled->regmap, wled->ctrl_addr + WLED3_CTRL_REG_MOD_EN,
> +			 &mod_en);
> +	if (rc < 0)
> +		return rc;
> +
> +	if (mod_en & WLED3_CTRL_REG_MOD_EN_MASK)
> +		wled->brightness = val;
> +

[Severity: High]
This isn't a bug introduced by this patch, but WLED3 devices lack the
wled_auto_detection_required function handler:

drivers/video/backlight/qcom-wled.c:wled_configure() {
...
    case 3:
        u32_opts = wled3_opts;
        size = ARRAY_SIZE(wled3_opts);
        *cfg = wled3_config_defaults;
        wled->wled_set_brightness = wled3_set_brightness;
        wled->wled_sync_toggle = wled3_sync_toggle;
...
}

Does this lead to a NULL pointer dereference if the OVP IRQ fires?

drivers/video/backlight/qcom-wled.c:wled_ovp_irq_handler() {
...
    if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT) {
        if (wled->wled_auto_detection_required(wled)) {
            mutex_lock(&wled->lock);
...
}

[Severity: High]
This is a pre-existing issue, but the short IRQ handler unconditionally
re-enables the hardware module:

drivers/video/backlight/qcom-wled.c:wled_short_irq_handler() {
...
    rc = wled_module_enable(wled, true);
...
}

Does this override the software intentions if the backlight is logically OFF
(or being turned OFF) in wled->brightness when the short-circuit IRQ triggers?

This could cause the hardware backlight to become stuck ON, leading to permanent
battery drain and incorrect state.

[ ... ]
> @@ -1742,9 +1755,6 @@ static int wled_probe(struct platform_device *pdev)
>  	if (rc < 0)
>  		return rc;
>  
> -	val = WLED_DEFAULT_BRIGHTNESS;
> -	of_property_read_u32(pdev->dev.of_node, "default-brightness", &val);
> -
>  	memset(&props, 0, sizeof(struct backlight_properties));
>  	props.type = BACKLIGHT_RAW;
>  	props.brightness = val;

[Severity: High]
This is a pre-existing issue, but wled_probe() never calls
platform_set_drvdata() before returning successfully:

drivers/video/backlight/qcom-wled.c:wled_probe() {
...
    bl = devm_backlight_device_register(&pdev->dev, wled->name,
                                        &pdev->dev, wled,
                                        &wled_ops, &props);
    return PTR_ERR_OR_ZERO(bl);
}

Will this cause a guaranteed NULL pointer dereference in wled_remove() when
unbinding the driver?

drivers/video/backlight/qcom-wled.c:wled_remove() {
    struct wled *wled = platform_get_drvdata(pdev);

    mutex_destroy(&wled->lock);
...
}

[Severity: High]
This is another pre-existing issue, but tearing down synchronization primitives
in wled_remove() before the devm-managed backlight is unregistered creates a
use-after-free window.

drivers/video/backlight/qcom-wled.c:wled_remove() {
...
    mutex_destroy(&wled->lock);
    cancel_delayed_work_sync(&wled->ovp_work);
...
}

The backlight device is registered via devm_backlight_device_register(), meaning
it remains active until devres cleanup after wled_remove() returns.

Could this lead to lock corruption or use-after-free if userspace accesses the
sysfs interface concurrently while the driver is being removed?

drivers/video/backlight/qcom-wled.c:wled_update_status() {
...
    mutex_lock(&wled->lock);
...
}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260908-qcom-wled-backlight-v1-1-c4dd4eabda07@ixit.cz?part=1

  reply	other threads:[~2026-09-08 21:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 20:53 [PATCH] backlight: qcom-wled: Fix unbalanced OVP IRQ enable at probe David Heidelberg via B4 Relay
2026-09-08 20:53 ` David Heidelberg
2026-09-08 21:09 ` sashiko-bot [this message]
2026-09-09  9:18 ` Konrad Dybcio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260908210947.099E21F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=david@ixit.cz \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.