From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9148A17DFFA; Sat, 12 Sep 2026 09:54:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789206843; cv=none; b=KiZqFljxt9H6de7Xsxm73VQEL9gDfZI5iHnL/HsGs1lpQeczt7hWTeSrhtMsuDJVlGdpHRRKIOMdW3127XDobKOp4LLuCr693PwfKw16ddBAbvl8NmsCZHXbC4F+8Oh5J0zaQUbrcgRARmcxIOrY2R0o93zy1+QINtgV4vyOR6E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789206843; c=relaxed/simple; bh=XVccJqorxBtC69Ms5haswlYYSSB5x8N35snBuMwdMWQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O/UTU0y6MA70Luz0pNjZoNHsgzvz1J+DmTQdtwAnsENC6cXzKy+mYD0kiC7irbLyAtcxknyBA2QeA26Dw0tpUahctJLzzQDt5LWtroYQYoMPOCVHTiCcAkl4PaAaHPXsBZ0bBJZuVvuY+zcHZSbBnBCff0+lmSw0nRlLXCRpB6U= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=O0DLzk1F; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="O0DLzk1F" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 401DC1F000FF; Sat, 12 Sep 2026 09:54:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1789206842; bh=pK0YHVAuTK7JpcZ0mj7VFvHFAq+myNbB7fLKOyQrE8Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=O0DLzk1F5sv51WmloSAGdD2ylipIF1A96m6IYHPWh0WACzft74/Z5B/6mNeL/Pfsr HVHVE1AwKRDiaEgkusipY/+wCvmWPDxpBCFLpk1tSJZJPtvrGmQyGCGNbZ0VQ8AWAc pJeM6SCCJkI6pgC1A3rOm0FuXvse+b60sjSFxHSk= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Manuel Fombuena , Lee Jones , Sasha Levin Subject: [PATCH 6.18 0291/1518] leds: st1202: Disable channel when brightness is set to zero Date: Sat, 12 Sep 2026 08:41:00 +0200 Message-ID: <20260912065630.064405951@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260912065623.398859879@linuxfoundation.org> References: <20260912065623.398859879@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Manuel Fombuena [ Upstream commit 0767335233a8cbab00bbe260a4e4bd380c7677fd ] When brightness_set() is called with LED_OFF, only the ILED register is zeroed; the channel enable bit is left set from probe time. A hardware channel enabled with ILED=0 still draws a small residual current, causing a dim glow even when the LED is supposed to be off. Fix this by splitting st1202_channel_set() into a lockless inner function __st1202_channel_set() and a locking wrapper, then calling the inner function from brightness_set() while it already holds the mutex. The channel is now disabled when value is zero and re-enabled when non-zero, in the same lock region as the ILED write. Fixes: 259230378c65 ("leds: Add LED1202 I2C driver") Signed-off-by: Manuel Fombuena Assisted-by: Claude:claude-sonnet-4-6 Link: https://patch.msgid.link/GV1PR08MB8497F11B30FE7D74CAA25135C5F52@GV1PR08MB8497.eurprd08.prod.outlook.com Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/leds/leds-st1202.c | 68 ++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c index 680ccb4395773..61b7fe715b880 100644 --- a/drivers/leds/leds-st1202.c +++ b/drivers/leds/leds-st1202.c @@ -129,39 +129,11 @@ static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern, st1202_prescalar_to_miliseconds(value)); } -static void st1202_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct st1202_led *led = cdev_to_st1202_led(led_cdev); - struct st1202_chip *chip = led->chip; - - guard(mutex)(&chip->lock); - - for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) - st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL); - st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value); -} - -static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev) -{ - struct st1202_led *led = cdev_to_st1202_led(led_cdev); - struct st1202_chip *chip = led->chip; - u8 value = 0; - - guard(mutex)(&chip->lock); - - st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value); - - return value; -} - -static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active) +static int __st1202_channel_set(struct st1202_chip *chip, int led_num, bool active) { u8 chan_low, chan_high; int ret; - guard(mutex)(&chip->lock); - if (led_num <= 7) { ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low); if (ret < 0) @@ -189,6 +161,40 @@ static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active return 0; } +static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active) +{ + guard(mutex)(&chip->lock); + + return __st1202_channel_set(chip, led_num, active); +} + +static void st1202_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct st1202_led *led = cdev_to_st1202_led(led_cdev); + struct st1202_chip *chip = led->chip; + + guard(mutex)(&chip->lock); + + for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) + st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL); + st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value); + __st1202_channel_set(chip, led->led_num, !!value); +} + +static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev) +{ + struct st1202_led *led = cdev_to_st1202_led(led_cdev); + struct st1202_chip *chip = led->chip; + u8 value = 0; + + guard(mutex)(&chip->lock); + + st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value); + + return value; +} + static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value) { struct st1202_led *led = cdev_to_st1202_led(ldev); @@ -256,6 +262,10 @@ static int st1202_led_pattern_set(struct led_classdev *ldev, if (ret != 0) return ret; + ret = __st1202_channel_set(chip, led->led_num, true); + if (ret != 0) + return ret; + ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR | ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT)); if (ret != 0) -- 2.53.0