Skip to content

Commit 63ef91f

Browse files
Marc Zyngierchanwoochoi
authored andcommitted
PM / devfreq: rk3399_dmc: Fix kernel oops when rockchip,pmu is absent
Booting a recent kernel on a rk3399-based system (nanopc-t4), equipped with a recent u-boot and ATF results in an Oops due to a NULL pointer dereference. This turns out to be due to the rk3399-dmc driver looking for an *undocumented* property (rockchip,pmu), and happily using a NULL pointer when the property isn't there. Instead, make most of what was brought in with 9173c5c ("PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.") conditioned on finding this property in the device-tree, preventing the driver from exploding. Cc: [email protected] Fixes: 9173c5c ("PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.") Signed-off-by: Marc Zyngier <[email protected]> Signed-off-by: Chanwoo Choi <[email protected]>
1 parent 92ed301 commit 63ef91f

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

drivers/devfreq/rk3399_dmc.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,20 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
9595

9696
mutex_lock(&dmcfreq->lock);
9797

98-
if (target_rate >= dmcfreq->odt_dis_freq)
99-
odt_enable = true;
100-
101-
/*
102-
* This makes a SMC call to the TF-A to set the DDR PD (power-down)
103-
* timings and to enable or disable the ODT (on-die termination)
104-
* resistors.
105-
*/
106-
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
107-
dmcfreq->odt_pd_arg1,
108-
ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
109-
odt_enable, 0, 0, 0, &res);
98+
if (dmcfreq->regmap_pmu) {
99+
if (target_rate >= dmcfreq->odt_dis_freq)
100+
odt_enable = true;
101+
102+
/*
103+
* This makes a SMC call to the TF-A to set the DDR PD
104+
* (power-down) timings and to enable or disable the
105+
* ODT (on-die termination) resistors.
106+
*/
107+
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
108+
dmcfreq->odt_pd_arg1,
109+
ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
110+
odt_enable, 0, 0, 0, &res);
111+
}
110112

111113
/*
112114
* If frequency scaling from low to high, adjust voltage first.
@@ -371,13 +373,14 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
371373
}
372374

373375
node = of_parse_phandle(np, "rockchip,pmu", 0);
374-
if (node) {
375-
data->regmap_pmu = syscon_node_to_regmap(node);
376-
of_node_put(node);
377-
if (IS_ERR(data->regmap_pmu)) {
378-
ret = PTR_ERR(data->regmap_pmu);
379-
goto err_edev;
380-
}
376+
if (!node)
377+
goto no_pmu;
378+
379+
data->regmap_pmu = syscon_node_to_regmap(node);
380+
of_node_put(node);
381+
if (IS_ERR(data->regmap_pmu)) {
382+
ret = PTR_ERR(data->regmap_pmu);
383+
goto err_edev;
381384
}
382385

383386
regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
@@ -399,6 +402,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
399402
goto err_edev;
400403
};
401404

405+
no_pmu:
402406
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
403407
ROCKCHIP_SIP_CONFIG_DRAM_INIT,
404408
0, 0, 0, 0, &res);

0 commit comments

Comments
 (0)