Commit e52fec7c authored by Federico Vaga's avatar Federico Vaga

sw:drv: do not use devm_*

It looks like there is a bug somewhere that make the system panic
on resource releasing. I can't provide any evidence that devm_* is
related to the issue, but removing it seems to solve the problem
(or at least is not as frequent as before: I can load/unload 100 times
without problems).

The problem was mitigated also by introducing delays (mdelay/printk)
in the fcl/gpio remove functions.

My guess is that MFD removal and devres clean up conflicts at some
point. MFD uses platform_unregister() which does resource_release(),
and because of devres, only after that we will release all resources
that we took on probe(). The flow does not sound right, we should
release resources we took **before** platform releases/remove the
resource from the system (not viceversa).
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 392c01eb
......@@ -519,7 +519,7 @@ static int gn412x_fcl_probe(struct platform_device *pdev)
struct resource *r;
int err;
gn412x = devm_kzalloc(&pdev->dev, sizeof(*gn412x), GFP_KERNEL);
gn412x = kzalloc(sizeof(*gn412x), GFP_KERNEL);
if (!gn412x)
return -ENOMEM;
platform_set_drvdata(pdev, gn412x);
......@@ -530,7 +530,7 @@ static int gn412x_fcl_probe(struct platform_device *pdev)
err = -EINVAL;
goto err_res_mem;
}
gn412x->mem = devm_ioremap(&pdev->dev, r->start, resource_size(r));
gn412x->mem = ioremap(r->start, resource_size(r));
if (!gn412x->mem) {
err = -EADDRNOTAVAIL;
goto err_map;
......@@ -558,10 +558,10 @@ err_fpga_reg:
compat_fpga_mgr_free(gn412x->mgr);
err_fpga_create:
gn4124_dbg_exit(pdev);
devm_iounmap(&pdev->dev, gn412x->mem);
iounmap(gn412x->mem);
err_map:
err_res_mem:
devm_kfree(&pdev->dev, gn412x);
kfree(gn412x);
platform_set_drvdata(pdev, NULL);
return err;
......@@ -571,15 +571,19 @@ static int gn412x_fcl_remove(struct platform_device *pdev)
{
struct gn412x_fcl_dev *gn412x = platform_get_drvdata(pdev);
gn4124_dbg_exit(pdev);
if (!gn412x->mgr)
return -ENODEV;
compat_fpga_mgr_unregister(gn412x->mgr);
compat_fpga_mgr_free(gn412x->mgr);
gn4124_dbg_exit(pdev);
iounmap(gn412x->mem);
kfree(gn412x);
platform_set_drvdata(pdev, NULL);
dev_dbg(&pdev->dev, "%s\n", __func__);
return 0;
}
......
......@@ -476,7 +476,7 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
struct resource *r;
int err;
gn412x = devm_kzalloc(&pdev->dev, sizeof(*gn412x), GFP_KERNEL);
gn412x = kzalloc(sizeof(*gn412x), GFP_KERNEL);
if (!gn412x)
return -ENOMEM;
......@@ -488,7 +488,7 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
err = -EINVAL;
goto err_res_mem;
}
gn412x->mem = devm_ioremap(&pdev->dev, r->start, resource_size(r));
gn412x->mem = ioremap(r->start, resource_size(r));
if (!gn412x->mem) {
err = -EADDRNOTAVAIL;
goto err_map;
......@@ -552,10 +552,10 @@ err_req:
err_add_irq:
gpiochip_remove(&gn412x->gpiochip);
err_add:
devm_iounmap(&pdev->dev, gn412x->mem);
iounmap(gn412x->mem);
err_map:
err_res_mem:
devm_kfree(&pdev->dev, gn412x);
kfree(gn412x);
return err;
}
......@@ -563,6 +563,7 @@ static int gn412x_gpio_remove(struct platform_device *pdev)
{
struct gn412x_gpio_dev *gn412x = platform_get_drvdata(pdev);
gn412x_dbg_exit(gn412x);
gn412x_gpio_int_cfg_disable(gn412x);
......@@ -570,6 +571,8 @@ static int gn412x_gpio_remove(struct platform_device *pdev)
free_irq(platform_get_irq(pdev, 0), gn412x);
gn412x_gpio_irq_set_nested_thread_all(gn412x, false);
gpiochip_remove(&gn412x->gpiochip);
iounmap(gn412x->mem);
kfree(gn412x);
dev_dbg(&pdev->dev, "%s\n", __func__);
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment