Skip to content

Commit

Permalink
soc: brcmstb: pm-arm: Fix refcount leak and __iomem leak bugs
Browse files Browse the repository at this point in the history
[ Upstream commit 1085f50 ]

In brcmstb_pm_probe(), there are two kinds of leak bugs:

(1) we need to add of_node_put() when for_each__matching_node() breaks
(2) we need to add iounmap() for each iomap in fail path

Fixes: 0b741b8 ("soc: bcm: brcmstb: Add support for S2/S3/S5 suspend states (ARM)")
Signed-off-by: Liang He <windhl@126.com>
Link: https://lore.kernel.org/r/20220707015620.306468-1-windhl@126.com
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
windhl authored and gregkh committed Sep 15, 2022
1 parent 811b2bf commit 653500b
Showing 1 changed file with 39 additions and 11 deletions.
50 changes: 39 additions & 11 deletions drivers/soc/bcm/brcmstb/pm/pm-arm.c
Expand Up @@ -684,13 +684,14 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
const struct of_device_id *of_id = NULL;
struct device_node *dn;
void __iomem *base;
int ret, i;
int ret, i, s;

/* AON ctrl registers */
base = brcmstb_ioremap_match(aon_ctrl_dt_ids, 0, NULL);
if (IS_ERR(base)) {
pr_err("error mapping AON_CTRL\n");
return PTR_ERR(base);
ret = PTR_ERR(base);
goto aon_err;
}
ctrl.aon_ctrl_base = base;

Expand All @@ -700,8 +701,10 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
/* Assume standard offset */
ctrl.aon_sram = ctrl.aon_ctrl_base +
AON_CTRL_SYSTEM_DATA_RAM_OFS;
s = 0;
} else {
ctrl.aon_sram = base;
s = 1;
}

writel_relaxed(0, ctrl.aon_sram + AON_REG_PANIC);
Expand All @@ -711,7 +714,8 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
(const void **)&ddr_phy_data);
if (IS_ERR(base)) {
pr_err("error mapping DDR PHY\n");
return PTR_ERR(base);
ret = PTR_ERR(base);
goto ddr_phy_err;
}
ctrl.support_warm_boot = ddr_phy_data->supports_warm_boot;
ctrl.pll_status_offset = ddr_phy_data->pll_status_offset;
Expand All @@ -731,17 +735,20 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
for_each_matching_node(dn, ddr_shimphy_dt_ids) {
i = ctrl.num_memc;
if (i >= MAX_NUM_MEMC) {
of_node_put(dn);
pr_warn("too many MEMCs (max %d)\n", MAX_NUM_MEMC);
break;
}

base = of_io_request_and_map(dn, 0, dn->full_name);
if (IS_ERR(base)) {
of_node_put(dn);
if (!ctrl.support_warm_boot)
break;

pr_err("error mapping DDR SHIMPHY %d\n", i);
return PTR_ERR(base);
ret = PTR_ERR(base);
goto ddr_shimphy_err;
}
ctrl.memcs[i].ddr_shimphy_base = base;
ctrl.num_memc++;
Expand All @@ -752,14 +759,18 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
for_each_matching_node(dn, brcmstb_memc_of_match) {
base = of_iomap(dn, 0);
if (!base) {
of_node_put(dn);
pr_err("error mapping DDR Sequencer %d\n", i);
return -ENOMEM;
ret = -ENOMEM;
goto brcmstb_memc_err;
}

of_id = of_match_node(brcmstb_memc_of_match, dn);
if (!of_id) {
iounmap(base);
return -EINVAL;
of_node_put(dn);
ret = -EINVAL;
goto brcmstb_memc_err;
}

ddr_seq_data = of_id->data;
Expand All @@ -779,21 +790,24 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
dn = of_find_matching_node(NULL, sram_dt_ids);
if (!dn) {
pr_err("SRAM not found\n");
return -EINVAL;
ret = -EINVAL;
goto brcmstb_memc_err;
}

ret = brcmstb_init_sram(dn);
of_node_put(dn);
if (ret) {
pr_err("error setting up SRAM for PM\n");
return ret;
goto brcmstb_memc_err;
}

ctrl.pdev = pdev;

ctrl.s3_params = kmalloc(sizeof(*ctrl.s3_params), GFP_KERNEL);
if (!ctrl.s3_params)
return -ENOMEM;
if (!ctrl.s3_params) {
ret = -ENOMEM;
goto s3_params_err;
}
ctrl.s3_params_pa = dma_map_single(&pdev->dev, ctrl.s3_params,
sizeof(*ctrl.s3_params),
DMA_TO_DEVICE);
Expand All @@ -813,7 +827,21 @@ static int brcmstb_pm_probe(struct platform_device *pdev)

out:
kfree(ctrl.s3_params);

s3_params_err:
iounmap(ctrl.boot_sram);
brcmstb_memc_err:
for (i--; i >= 0; i--)
iounmap(ctrl.memcs[i].ddr_ctrl);
ddr_shimphy_err:
for (i = 0; i < ctrl.num_memc; i++)
iounmap(ctrl.memcs[i].ddr_shimphy_base);

iounmap(ctrl.memcs[0].ddr_phy_base);
ddr_phy_err:
iounmap(ctrl.aon_ctrl_base);
if (s)
iounmap(ctrl.aon_sram);
aon_err:
pr_warn("PM: initialization failed with code %d\n", ret);

return ret;
Expand Down

0 comments on commit 653500b

Please sign in to comment.