[PATCH v2] power: supply: ds2760_battery: convert to devm-managed workqueue and pm_notifier

Ivy Lopez <[email protected]>
Newsgroups org.kernel.vger.linux-pm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Following review feedback, convert the driver to use devm-managed
resources instead of manual cleanup in w1_ds2760_remove_slave():

- devm_alloc_ordered_workqueue() for the monitor workqueue
- devm_delayed_work_autocancel() for the monitor delayed work
- devm_add_action_or_reset() to unregister the pm_notifier

This removes the need for w1_ds2760_remove_slave() entirely, along
with the NULL checks it required to safely handle a partially
initialized di on an add_slave() failure path.

Fixes: bf4973553737 ("power: supply: ds2760_battery: merge ds2760 supply driver with its w1 slave companion")
Suggested-by: Sebastian Reichel <[email protected]>
Signed-off-by: Ivy Lopez <[email protected]>
---
 drivers/power/supply/ds2760_battery.c | 54 +++++++++++----------------
 1 file changed, 21 insertions(+), 33 deletions(-)

diff --git a/drivers/power/supply/ds2760_battery.c b/drivers/power/supply/ds2760_battery.c
index 3c2433f6b5e9..901aaaf916c4 100644
--- a/drivers/power/supply/ds2760_battery.c
+++ b/drivers/power/supply/ds2760_battery.c
@@ -23,6 +23,7 @@
 #include <linux/param.h>
 #include <linux/jiffies.h>
 #include <linux/workqueue.h>
+#include <linux/devm-helpers.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
@@ -621,6 +622,11 @@ static int ds2760_pm_notifier(struct notifier_block *notifier,
 	return NOTIFY_DONE;
 }
 
+static void ds2760_battery_unregister_pm_notifier(void *notifier)
+{
+	unregister_pm_notifier(notifier);
+}
+
 static int w1_ds2760_add_slave(struct w1_slave *sl)
 {
 	struct power_supply_config psy_cfg = {};
@@ -631,10 +637,8 @@ static int w1_ds2760_add_slave(struct w1_slave *sl)
 	char status;
 
 	di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL);
-	if (!di) {
-		retval = -ENOMEM;
-		goto di_alloc_failed;
-	}
+	if (!di)
+		return -ENOMEM;
 
 	snprintf(name, sizeof(name), "ds2760-battery.%d", dev->id);
 
@@ -695,41 +699,26 @@ static int w1_ds2760_add_slave(struct w1_slave *sl)
 	di->bat = devm_power_supply_register(dev, &di->bat_desc, &psy_cfg);
 	if (IS_ERR(di->bat)) {
 		dev_err(di->dev, "failed to register battery\n");
-		retval = PTR_ERR(di->bat);
-		goto batt_failed;
+		return PTR_ERR(di->bat);
 	}
 
-	INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
-	di->monitor_wqueue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM);
-	if (!di->monitor_wqueue) {
-		retval = -ESRCH;
-		goto workqueue_failed;
-	}
+	di->monitor_wqueue = devm_alloc_ordered_workqueue(dev, name, WQ_MEM_RECLAIM);
+	if (!di->monitor_wqueue)
+		return -ESRCH;
+
+	retval = devm_delayed_work_autocancel(dev, &di->monitor_work,
+						 ds2760_battery_work);
+	if (retval)
+		return retval;
+
 	queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1);
 
 	di->pm_notifier.notifier_call = ds2760_pm_notifier;
 	register_pm_notifier(&di->pm_notifier);
 
-	goto success;
-
-workqueue_failed:
-batt_failed:
-di_alloc_failed:
-success:
-	return retval;
-}
-
-static void w1_ds2760_remove_slave(struct w1_slave *sl)
-{
-	struct ds2760_device_info *di = sl->family_data;
-
-	if (!di)
-		return;
-
-	unregister_pm_notifier(&di->pm_notifier);
-	cancel_delayed_work_sync(&di->monitor_work);
-	if (di->monitor_wqueue)
-		destroy_workqueue(di->monitor_wqueue);
+	return devm_add_action_or_reset(dev,
+					   ds2760_battery_unregister_pm_notifier,
+					   &di->pm_notifier);
 }
 
 #ifdef CONFIG_OF
@@ -741,7 +730,6 @@ static const struct of_device_id w1_ds2760_of_ids[] = {
 
 static const struct w1_family_ops w1_ds2760_fops = {
 	.add_slave	= w1_ds2760_add_slave,
-	.remove_slave	= w1_ds2760_remove_slave,
 	.groups		= w1_ds2760_groups,
 };
 
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.