Commit 63ef91f2 authored by Marc Zyngier's avatar Marc Zyngier Committed by Chanwoo Choi

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 9173c5ce
("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: stable@vger.kernel.org
Fixes: 9173c5ce ("PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.")
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
parent 92ed3019
...@@ -95,18 +95,20 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq, ...@@ -95,18 +95,20 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
mutex_lock(&dmcfreq->lock); mutex_lock(&dmcfreq->lock);
if (dmcfreq->regmap_pmu) {
if (target_rate >= dmcfreq->odt_dis_freq) if (target_rate >= dmcfreq->odt_dis_freq)
odt_enable = true; odt_enable = true;
/* /*
* This makes a SMC call to the TF-A to set the DDR PD (power-down) * This makes a SMC call to the TF-A to set the DDR PD
* timings and to enable or disable the ODT (on-die termination) * (power-down) timings and to enable or disable the
* resistors. * ODT (on-die termination) resistors.
*/ */
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0, arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
dmcfreq->odt_pd_arg1, dmcfreq->odt_pd_arg1,
ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
odt_enable, 0, 0, 0, &res); odt_enable, 0, 0, 0, &res);
}
/* /*
* If frequency scaling from low to high, adjust voltage first. * If frequency scaling from low to high, adjust voltage first.
...@@ -371,14 +373,15 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) ...@@ -371,14 +373,15 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
} }
node = of_parse_phandle(np, "rockchip,pmu", 0); node = of_parse_phandle(np, "rockchip,pmu", 0);
if (node) { if (!node)
goto no_pmu;
data->regmap_pmu = syscon_node_to_regmap(node); data->regmap_pmu = syscon_node_to_regmap(node);
of_node_put(node); of_node_put(node);
if (IS_ERR(data->regmap_pmu)) { if (IS_ERR(data->regmap_pmu)) {
ret = PTR_ERR(data->regmap_pmu); ret = PTR_ERR(data->regmap_pmu);
goto err_edev; goto err_edev;
} }
}
regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val); regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) & ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
...@@ -399,6 +402,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) ...@@ -399,6 +402,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
goto err_edev; goto err_edev;
}; };
no_pmu:
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
ROCKCHIP_SIP_CONFIG_DRAM_INIT, ROCKCHIP_SIP_CONFIG_DRAM_INIT,
0, 0, 0, 0, &res); 0, 0, 0, 0, &res);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment