* [PATCH 5.15.y 2/5] leds: lm3697: Remove duplicated error reporting in .remove()
2026-07-20 2:25 ` [PATCH 5.15.y 1/5] drm/i2c/sil164: Drop no-op remove function Sasha Levin
@ 2026-07-20 2:25 ` Sasha Levin
2026-07-20 2:25 ` [PATCH 5.15.y 3/5] leds: lm3601x: Improve error reporting for problems during .remove() Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-20 2:25 UTC (permalink / raw)
To: stable; +Cc: Uwe Kleine-König, Pavel Machek, Wolfram Sang, Sasha Levin
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit af89fa11fae1cee4e07453f780e6e5573ef0f477 ]
Returning an error value from an i2c remove callback results in an error
message being emitted by the i2c core, but otherwise it doesn't make a
difference. The device goes away anyhow and the devm cleanups are
called.
As lm3697_remove() already emits an error message on failure and the
additional error message by the i2c core doesn't add any useful
information, don't pass the error value up the stack. Instead continue
to clean up and return 0.
This patch is a preparation for making i2c remove callbacks return void.
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/leds/leds-lm3697.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/leds/leds-lm3697.c b/drivers/leds/leds-lm3697.c
index a8c9322558cc51..3ecf90fbc06c09 100644
--- a/drivers/leds/leds-lm3697.c
+++ b/drivers/leds/leds-lm3697.c
@@ -345,10 +345,8 @@ static int lm3697_remove(struct i2c_client *client)
ret = regmap_update_bits(led->regmap, LM3697_CTRL_ENABLE,
LM3697_CTRL_A_B_EN, 0);
- if (ret) {
+ if (ret)
dev_err(dev, "Failed to disable the device\n");
- return ret;
- }
if (led->enable_gpio)
gpiod_direction_output(led->enable_gpio, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 3/5] leds: lm3601x: Improve error reporting for problems during .remove()
2026-07-20 2:25 ` [PATCH 5.15.y 1/5] drm/i2c/sil164: Drop no-op remove function Sasha Levin
2026-07-20 2:25 ` [PATCH 5.15.y 2/5] leds: lm3697: Remove duplicated error reporting in .remove() Sasha Levin
@ 2026-07-20 2:25 ` Sasha Levin
2026-07-20 2:25 ` [PATCH 5.15.y 4/5] gpio: pca953x: Make platform teardown callback return void Sasha Levin
2026-07-20 2:25 ` [PATCH 5.15.y 5/5] usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-20 2:25 UTC (permalink / raw)
To: stable; +Cc: Uwe Kleine-König, Pavel Machek, Wolfram Sang, Sasha Levin
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit 22a23436891886a66d21af3619f4a4e8809f0e0a ]
Returning an error value in an i2c remove callback results in a generic
error message being emitted by the i2c core, but otherwise it doesn't
make a difference. The device goes away anyhow and the devm cleanups are
called.
So instead of triggering the generic i2c error message, emit a more
helpful message if a problem occurs and return 0 to suppress the generic
message.
This patch is a preparation for making i2c remove callbacks return void.
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/leds/flash/leds-lm3601x.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/leds/flash/leds-lm3601x.c b/drivers/leds/flash/leds-lm3601x.c
index 3d127274820173..37e1d6e6868777 100644
--- a/drivers/leds/flash/leds-lm3601x.c
+++ b/drivers/leds/flash/leds-lm3601x.c
@@ -443,10 +443,15 @@ static int lm3601x_probe(struct i2c_client *client)
static int lm3601x_remove(struct i2c_client *client)
{
struct lm3601x_led *led = i2c_get_clientdata(client);
+ int ret;
- return regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
- LM3601X_ENABLE_MASK,
- LM3601X_MODE_STANDBY);
+ ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+ LM3601X_ENABLE_MASK, LM3601X_MODE_STANDBY);
+ if (ret)
+ dev_warn(&client->dev,
+ "Failed to put into standby (%pe)\n", ERR_PTR(ret));
+
+ return 0;
}
static const struct i2c_device_id lm3601x_id[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 4/5] gpio: pca953x: Make platform teardown callback return void
2026-07-20 2:25 ` [PATCH 5.15.y 1/5] drm/i2c/sil164: Drop no-op remove function Sasha Levin
2026-07-20 2:25 ` [PATCH 5.15.y 2/5] leds: lm3697: Remove duplicated error reporting in .remove() Sasha Levin
2026-07-20 2:25 ` [PATCH 5.15.y 3/5] leds: lm3601x: Improve error reporting for problems during .remove() Sasha Levin
@ 2026-07-20 2:25 ` Sasha Levin
2026-07-20 2:25 ` [PATCH 5.15.y 5/5] usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-20 2:25 UTC (permalink / raw)
To: stable
Cc: Uwe Kleine-König, Andy Shevchenko, Bartosz Golaszewski,
Wolfram Sang, Sasha Levin
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit 6a8f359c3132e4f51bdb263ad74ec632c65e55fd ]
All platforms that provide a teardown callback return 0. New users are
supposed to not make use of platform support, so there is no
functionality lost.
This patch is a preparation for making i2c remove callbacks return void.
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Bartosz Golaszewski <brgl@bgdev.pl>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Stable-dep-of: 1f0bdc2884b6 ("usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm/mach-davinci/board-da850-evm.c | 12 ++++--------
drivers/gpio/gpio-pca953x.c | 11 +++--------
include/linux/platform_data/pca953x.h | 2 +-
3 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 1601a74261a67b..71bd7c53048c5c 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -517,8 +517,8 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
return ret;
}
-static int da850_evm_ui_expander_teardown(struct i2c_client *client,
- unsigned gpio, unsigned ngpio, void *c)
+static void da850_evm_ui_expander_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *c)
{
platform_device_unregister(&da850_evm_ui_keys_device);
@@ -530,8 +530,6 @@ static int da850_evm_ui_expander_teardown(struct i2c_client *client,
gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
-
- return 0;
}
/* assign the baseboard expander's GPIOs after the UI board's */
@@ -698,13 +696,11 @@ static int da850_evm_bb_expander_setup(struct i2c_client *client,
return ret;
}
-static int da850_evm_bb_expander_teardown(struct i2c_client *client,
- unsigned gpio, unsigned ngpio, void *c)
+static void da850_evm_bb_expander_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *c)
{
platform_device_unregister(&da850_evm_bb_leds_device);
platform_device_unregister(&da850_evm_bb_keys_device);
-
- return 0;
}
static struct pca953x_platform_data da850_evm_ui_expander_info = {
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index a8f6ef4006fef9..94c888510243c2 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -1074,20 +1074,15 @@ static int pca953x_remove(struct i2c_client *client)
{
struct pca953x_platform_data *pdata = dev_get_platdata(&client->dev);
struct pca953x_chip *chip = i2c_get_clientdata(client);
- int ret;
if (pdata && pdata->teardown) {
- ret = pdata->teardown(client, chip->gpio_chip.base,
- chip->gpio_chip.ngpio, pdata->context);
- if (ret < 0)
- dev_err(&client->dev, "teardown failed, %d\n", ret);
- } else {
- ret = 0;
+ pdata->teardown(client, chip->gpio_chip.base,
+ chip->gpio_chip.ngpio, pdata->context);
}
regulator_disable(chip->regulator);
- return ret;
+ return 0;
}
#ifdef CONFIG_PM_SLEEP
diff --git a/include/linux/platform_data/pca953x.h b/include/linux/platform_data/pca953x.h
index 4eb53e02399786..96c1a14ab3657a 100644
--- a/include/linux/platform_data/pca953x.h
+++ b/include/linux/platform_data/pca953x.h
@@ -22,7 +22,7 @@ struct pca953x_platform_data {
int (*setup)(struct i2c_client *client,
unsigned gpio, unsigned ngpio,
void *context);
- int (*teardown)(struct i2c_client *client,
+ void (*teardown)(struct i2c_client *client,
unsigned gpio, unsigned ngpio,
void *context);
const char *const *names;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 5/5] usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove
2026-07-20 2:25 ` [PATCH 5.15.y 1/5] drm/i2c/sil164: Drop no-op remove function Sasha Levin
` (2 preceding siblings ...)
2026-07-20 2:25 ` [PATCH 5.15.y 4/5] gpio: pca953x: Make platform teardown callback return void Sasha Levin
@ 2026-07-20 2:25 ` Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-20 2:25 UTC (permalink / raw)
To: stable; +Cc: Fan Wu, stable, Heikki Krogerus, Greg Kroah-Hartman, Sasha Levin
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 1f0bdc2884b67de337215079bba166df0cdf4ac5 ]
The threaded IRQ handler ccg_irq_handler() calls ucsi_notify_common(),
which on a connector-change event calls ucsi_connector_change() and
schedules connector work. In ucsi_ccg_remove(), ucsi_destroy() frees
uc->ucsi (kfree) before free_irq() is called, so a handler invocation
already in flight may access the freed object after ucsi_destroy().
CPU 0 (remove) | CPU 1 (threaded IRQ)
ucsi_destroy(uc->ucsi) | ccg_irq_handler()
kfree(ucsi) // FREE | ucsi_notify_common(uc->ucsi) // USE
Move free_irq() before ucsi_destroy() in the remove path. It is kept
after ucsi_unregister(): ucsi_unregister() cancels connector work whose
handler issues GET_CONNECTOR_STATUS through ucsi_send_command_common(),
which waits for a completion that is signalled from the IRQ handler, so
the IRQ must stay active until that work has been cancelled.
The probe error path already orders free_irq() before ucsi_destroy().
This bug was found by static analysis.
Fixes: e32fd989ac1c ("usb: typec: ucsi: ccg: Move to the new API")
Cc: stable <stable@kernel.org>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260616132011.103279-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/ucsi/ucsi_ccg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 68a693d92dd05a..8d69bc5bff20a9 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -1418,8 +1418,8 @@ static int ucsi_ccg_remove(struct i2c_client *client)
cancel_work_sync(&uc->work);
pm_runtime_disable(uc->dev);
ucsi_unregister(uc->ucsi);
- ucsi_destroy(uc->ucsi);
free_irq(uc->irq, uc);
+ ucsi_destroy(uc->ucsi);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread