diff options
author | Anson Huang <Anson.Huang@nxp.com> | 2018-09-18 18:13:22 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:34:09 +0800 |
commit | 6ea87324a80669adfdb9453c8fc02c9eb382ab5e (patch) | |
tree | 6f62130dced1d91b72b8aad9e2cab4347cd67a1b /drivers/soc | |
parent | a9e43ebfcc86a974f8711090b8372375673a7b42 (diff) |
MLK-19612 soc: imx: fix kernel warning when detaching dev for certain power domain
For i.MX8QM/i.MX8QXP, one power domain could have several devices
inside, such as cs42888 and wm8960 both belong to pd_mclk_out0
power domain, when these two devices probed, imx8_attach_dev() will
be called and these two devices' clocks will be add to pd_mclk_out0's
clock list, then if the second device probe failed and imx8_detach_dev()
will be called, the original code will go through the whole pd_mclk_out0
power domian's clock list and delete all the clock nodes, when the
clock node are NOT belonging to this device, below kernel warning will
show out by devm_kfree() function:
[ 4.998488] [<ffff0000086a8cac>] devm_kfree+0x2c/0x38
[ 5.003543] [<ffff000008595b60>] imx8_detach_dev+0xb4/0x14c
[ 5.009121] [<ffff0000086b8e8c>] genpd_remove_device+0x70/0xe8
[ 5.014959] [<ffff0000086b98d8>] genpd_dev_pm_detach+0x3c/0xc8
[ 5.020797] [<ffff0000086adc68>] dev_pm_domain_detach+0x20/0x28
[ 5.026722] [<ffff000008928940>] i2c_device_probe+0x1d4/0x35c
[ 5.032472] [<ffff0000086a4d50>] driver_probe_device+0x220/0x2d4
[ 5.038484] [<ffff0000086a4ea8>] __driver_attach+0xa4/0xa8
[ 5.043978] [<ffff0000086a2ea4>] bus_for_each_dev+0x58/0x98
[ 5.049552] [<ffff0000086a4678>] driver_attach+0x20/0x28
[ 5.054869] [<ffff0000086a41f4>] bus_add_driver+0x1c0/0x224
[ 5.060446] [<ffff0000086a57cc>] driver_register+0x68/0x108
[ 5.066024] [<ffff00000892a35c>] i2c_register_driver+0x44/0x84
[ 5.071862] [<ffff0000093b68a4>] wm8960_i2c_driver_init+0x18/0x20
[ 5.077961] [<ffff000008084144>] do_one_initcall+0x38/0x124
[ 5.083538] [<ffff000009350d28>] kernel_init_freeable+0x18c/0x228
[ 5.089638] [<ffff000008d409c0>] kernel_init+0x10/0x100
[ 5.094869] [<ffff000008085348>] ret_from_fork+0x10/0x18
The correct operation is to just delete those clock nodes belonged
to the device being detached, to avoid this case, we can add a device
point which can be assigned to device during attach_dev phase, then
in detach_dev phase, check the device pointer to make sure ONLY delete
those clock nodes belonged to its own and keep other clock nodes in the
same power domain there.
Reported-by: Chen Guoyin <guoyin.chen@nxp.com>
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Reviewed-by: Bai Ping <ping.bai@nxp.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/imx/pm-domain-imx8.h | 1 | ||||
-rw-r--r-- | drivers/soc/imx/pm-domains.c | 4 |
2 files changed, 5 insertions, 0 deletions
diff --git a/drivers/soc/imx/pm-domain-imx8.h b/drivers/soc/imx/pm-domain-imx8.h index 58b5328e47e5..a9489a82d6f8 100644 --- a/drivers/soc/imx/pm-domain-imx8.h +++ b/drivers/soc/imx/pm-domain-imx8.h @@ -26,6 +26,7 @@ struct platform_device; struct imx8_pm_rsrc_clks { struct clk *clk; struct clk *parent; + struct device *dev; u32 rate; struct list_head node; }; diff --git a/drivers/soc/imx/pm-domains.c b/drivers/soc/imx/pm-domains.c index a3910ca35ae0..9a636dad1741 100644 --- a/drivers/soc/imx/pm-domains.c +++ b/drivers/soc/imx/pm-domains.c @@ -243,6 +243,7 @@ static int imx8_attach_dev(struct generic_pm_domain *genpd, struct device *dev) if (!imx8_rsrc_clk) return -ENOMEM; + imx8_rsrc_clk->dev = dev; imx8_rsrc_clk->clk = of_clk_get_from_provider(&clkspec); if (!IS_ERR(imx8_rsrc_clk->clk)) list_add_tail(&imx8_rsrc_clk->node, &pd->clks); @@ -262,6 +263,9 @@ static void imx8_detach_dev(struct generic_pm_domain *genpd, struct device *dev) return; list_for_each_entry_safe(imx8_rsrc_clk, tmp, &pd->clks, node) { + /* only delete those clocks belonged to this devive */ + if (imx8_rsrc_clk->dev != dev) + continue; list_del(&imx8_rsrc_clk->node); devm_kfree(dev, imx8_rsrc_clk); } |