summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuangshuo Li <lgs201920130244@gmail.com>2026-07-08 17:20:38 +0800
committerUlf Hansson <ulfh@kernel.org>2026-07-27 11:46:33 +0200
commit3e013bc8b941bd52c8e3a99798d0ae8792cb71ca (patch)
tree464b9cff252c31553f889387365dbc4d51db7df7
parentcbb0140379de69fa46526672f3003f128f0b4e2e (diff)
downloadlinux-next-3e013bc8b941bd52c8e3a99798d0ae8792cb71ca.tar.gz
linux-next-3e013bc8b941bd52c8e3a99798d0ae8792cb71ca.zip
pmdomain: mediatek: fix remaining %pOF after of_node_put()
scpsys_get_bus_protection_legacy() looks up several legacy bus protection regmaps from device-tree nodes. Two error paths put the device node before checking whether the regmap lookup failed, but still pass that node to dev_err_probe() with %pOF on failure. If of_node_put() drops the last reference, the later %pOF formatting can dereference a freed device node. Keep the node reference until after the error message has been emitted in the infracfg and SMI lookup paths. Also drop the SMI node before returning when the SMI phandle is missing. Fixes: c29345fa5f66 ("pmdomain: mediatek: Refactor bus protection regmaps retrieval") Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com> Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson <ulfh@kernel.org>
-rw-r--r--drivers/pmdomain/mediatek/mtk-pm-domains.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
index 881a1a3b3632..6089c8cf5bbc 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
@@ -1050,12 +1050,15 @@ static int scpsys_get_bus_protection_legacy(struct device *dev, struct scpsys *s
node = of_find_node_with_property(np, "mediatek,infracfg");
if (node) {
regmap[0] = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg");
- of_node_put(node);
num_regmaps++;
- if (IS_ERR(regmap[0]))
- return dev_err_probe(dev, PTR_ERR(regmap[0]),
+ if (IS_ERR(regmap[0])) {
+ ret = dev_err_probe(dev, PTR_ERR(regmap[0]),
"%pOF: failed to get infracfg regmap\n",
node);
+ of_node_put(node);
+ return ret;
+ }
+ of_node_put(node);
} else {
regmap[0] = NULL;
}
@@ -1064,17 +1067,22 @@ static int scpsys_get_bus_protection_legacy(struct device *dev, struct scpsys *s
node = of_find_node_with_property(np, "mediatek,smi");
if (node) {
smi_np = of_parse_phandle(node, "mediatek,smi", 0);
- of_node_put(node);
- if (!smi_np)
+ if (!smi_np) {
+ of_node_put(node);
return -ENODEV;
+ }
regmap[1] = device_node_to_regmap(smi_np);
num_regmaps++;
of_node_put(smi_np);
- if (IS_ERR(regmap[1]))
- return dev_err_probe(dev, PTR_ERR(regmap[1]),
+ if (IS_ERR(regmap[1])) {
+ ret = dev_err_probe(dev, PTR_ERR(regmap[1]),
"%pOF: failed to get SMI regmap\n",
node);
+ of_node_put(node);
+ return ret;
+ }
+ of_node_put(node);
} else {
regmap[1] = NULL;
}