summaryrefslogtreecommitdiff
path: root/drivers/soc/imx
diff options
context:
space:
mode:
authorAnson Huang <Anson.Huang@nxp.com>2018-09-18 18:13:22 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:34:09 +0800
commit6ea87324a80669adfdb9453c8fc02c9eb382ab5e (patch)
tree6f62130dced1d91b72b8aad9e2cab4347cd67a1b /drivers/soc/imx
parenta9e43ebfcc86a974f8711090b8372375673a7b42 (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/imx')
-rw-r--r--drivers/soc/imx/pm-domain-imx8.h1
-rw-r--r--drivers/soc/imx/pm-domains.c4
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);
}