mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 23:58:05 +00:00
power: supply: ab8500_fg: Allocate wq in probe
[ Upstream commit010ddb813f
] 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:1c1f13a006
("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
6bf660d4b6
commit
c9ce9b98a8
1 changed files with 10 additions and 9 deletions
|
@ -2995,13 +2995,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;
|
||||
|
@ -3025,8 +3018,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 = {
|
||||
|
@ -3070,6 +3062,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);
|
||||
|
||||
|
@ -3181,6 +3180,8 @@ static int ab8500_fg_remove(struct platform_device *pdev)
|
|||
int ret = 0;
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue