power: supply: axp288_charger: Do not cancel work before initializing it

Driver registered devm handler to cancel_work_sync() before even the
work was initialized, thus leading to possible warning from
kernel/workqueue.c on (!work->func) check, if the error path was hit
before the initialization happened.

Use devm_work_autocancel() on each work item independently, which
handles the initialization and handler to cancel work.

Fixes: 165c235774 ("power: supply: axp288_charger: Properly stop work on probe-error / remove")
Cc: stable@vger.kernel.org
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
Link: https://patch.msgid.link/20260220174938.672883-5-krzysztof.kozlowski@oss.qualcomm.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
This commit is contained in:
Krzysztof Kozlowski
2026-02-20 18:49:39 +01:00
committed by Sebastian Reichel
parent f0c8407c83
commit 658342fd75

View File

@@ -10,6 +10,7 @@
#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/devm-helpers.h>
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/workqueue.h>
@@ -821,14 +822,6 @@ static int charger_init_hw_regs(struct axp288_chrg_info *info)
return 0;
}
static void axp288_charger_cancel_work(void *data)
{
struct axp288_chrg_info *info = data;
cancel_work_sync(&info->otg.work);
cancel_work_sync(&info->cable.work);
}
static int axp288_charger_probe(struct platform_device *pdev)
{
int ret, i, pirq;
@@ -911,12 +904,12 @@ static int axp288_charger_probe(struct platform_device *pdev)
}
/* Cancel our work on cleanup, register this before the notifiers */
ret = devm_add_action(dev, axp288_charger_cancel_work, info);
ret = devm_work_autocancel(dev, &info->cable.work,
axp288_charger_extcon_evt_worker);
if (ret)
return ret;
/* Register for extcon notification */
INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker);
info->cable.nb.notifier_call = axp288_charger_handle_cable_evt;
ret = devm_extcon_register_notifier_all(dev, info->cable.edev,
&info->cable.nb);
@@ -926,8 +919,12 @@ static int axp288_charger_probe(struct platform_device *pdev)
}
schedule_work(&info->cable.work);
ret = devm_work_autocancel(dev, &info->otg.work,
axp288_charger_otg_evt_worker);
if (ret)
return ret;
/* Register for OTG notification */
INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker);
info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt;
if (info->otg.cable) {
ret = devm_extcon_register_notifier(dev, info->otg.cable,