Skip to content

Commit

Permalink
power: supply: ab8500_fg: Allocate wq in probe
Browse files Browse the repository at this point in the history
The workqueue is allocated in bind() but all interrupts are
registered in probe().

Some interrupts put work on the workqueue, which can have
bad side effects.

Allocate the workqueue in probe() instead, destroy it in
.remove() and make unbind() simply flush the workqueue.

Fixes: 1c1f13a ("power: supply: ab8500: Move to componentized binding")
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
  • Loading branch information
Linus Walleij authored and Sebastian Reichel committed May 3, 2022
1 parent f61509a commit 010ddb8
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions drivers/power/supply/ab8500_fg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3037,13 +3037,6 @@ static int ab8500_fg_bind(struct device *dev, struct device *master,
{
struct ab8500_fg *di = dev_get_drvdata(dev);

/* Create a work queue for running the FG algorithm */
di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM);
if (di->fg_wq == NULL) {
dev_err(dev, "failed to create work queue\n");
return -ENOMEM;
}

di->bat_cap.max_mah_design = di->bm->bi->charge_full_design_uah;
di->bat_cap.max_mah = di->bat_cap.max_mah_design;
di->vbat_nom_uv = di->bm->bi->voltage_max_design_uv;
Expand All @@ -3067,8 +3060,7 @@ static void ab8500_fg_unbind(struct device *dev, struct device *master,
if (ret)
dev_err(dev, "failed to disable coulomb counter\n");

destroy_workqueue(di->fg_wq);
flush_scheduled_work();
flush_workqueue(di->fg_wq);
}

static const struct component_ops ab8500_fg_component_ops = {
Expand Down Expand Up @@ -3117,6 +3109,13 @@ static int ab8500_fg_probe(struct platform_device *pdev)
ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_INIT);
ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_INIT);

/* Create a work queue for running the FG algorithm */
di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM);
if (di->fg_wq == NULL) {
dev_err(dev, "failed to create work queue\n");
return -ENOMEM;
}

/* Init work for running the fg algorithm instantly */
INIT_WORK(&di->fg_work, ab8500_fg_instant_work);

Expand Down Expand Up @@ -3227,6 +3226,8 @@ static int ab8500_fg_remove(struct platform_device *pdev)
{
struct ab8500_fg *di = platform_get_drvdata(pdev);

destroy_workqueue(di->fg_wq);
flush_scheduled_work();
component_del(&pdev->dev, &ab8500_fg_component_ops);
list_del(&di->node);
ab8500_fg_sysfs_exit(di);
Expand Down

0 comments on commit 010ddb8

Please sign in to comment.