Skip to content

Commit 010ddb8

Browse files
linuswsre
authored andcommitted
power: supply: ab8500_fg: Allocate wq in probe
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>
1 parent f61509a commit 010ddb8

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

drivers/power/supply/ab8500_fg.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3037,13 +3037,6 @@ static int ab8500_fg_bind(struct device *dev, struct device *master,
30373037
{
30383038
struct ab8500_fg *di = dev_get_drvdata(dev);
30393039

3040-
/* Create a work queue for running the FG algorithm */
3041-
di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM);
3042-
if (di->fg_wq == NULL) {
3043-
dev_err(dev, "failed to create work queue\n");
3044-
return -ENOMEM;
3045-
}
3046-
30473040
di->bat_cap.max_mah_design = di->bm->bi->charge_full_design_uah;
30483041
di->bat_cap.max_mah = di->bat_cap.max_mah_design;
30493042
di->vbat_nom_uv = di->bm->bi->voltage_max_design_uv;
@@ -3067,8 +3060,7 @@ static void ab8500_fg_unbind(struct device *dev, struct device *master,
30673060
if (ret)
30683061
dev_err(dev, "failed to disable coulomb counter\n");
30693062

3070-
destroy_workqueue(di->fg_wq);
3071-
flush_scheduled_work();
3063+
flush_workqueue(di->fg_wq);
30723064
}
30733065

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

3112+
/* Create a work queue for running the FG algorithm */
3113+
di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM);
3114+
if (di->fg_wq == NULL) {
3115+
dev_err(dev, "failed to create work queue\n");
3116+
return -ENOMEM;
3117+
}
3118+
31203119
/* Init work for running the fg algorithm instantly */
31213120
INIT_WORK(&di->fg_work, ab8500_fg_instant_work);
31223121

@@ -3227,6 +3226,8 @@ static int ab8500_fg_remove(struct platform_device *pdev)
32273226
{
32283227
struct ab8500_fg *di = platform_get_drvdata(pdev);
32293228

3229+
destroy_workqueue(di->fg_wq);
3230+
flush_scheduled_work();
32303231
component_del(&pdev->dev, &ab8500_fg_component_ops);
32313232
list_del(&di->node);
32323233
ab8500_fg_sysfs_exit(di);

0 commit comments

Comments
 (0)