mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
remoteproc: qcom_wcnss: Fix handling the lack of PD regulators in v3
The changes introduced to handle single power domain platforms have swapped the info pointer increment from num_pd_vregs to num_pds, which would shift the info pointer past the end of the array for pronto-v3, which does not list power domain regulators in vregs. This showed up as a difference between GCC- and LLVM-compiled kernels on SDM632 devices, where only with LLVM one would get the "regulator request with no identifier" error, because the out-of-bounds memory ended up being zeroed. Fix by skipping the increment when there are more power domains than regulators. Signed-off-by: Val Packett <val@packett.cool> Fixes:65991ea8a6("remoteproc: qcom_wcnss: Handle platforms with only single power domain") Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Fixes:65991ea8a6("remoteproc: qcom_wcnss: Handle platforms with only single power domain") Link: https://lore.kernel.org/r/20260201210230.911220-1-val@packett.cool Signed-off-by: Bjorn Andersson <andersson@kernel.org>
This commit is contained in:
parent
8c952807c2
commit
3dbc90b9c2
|
|
@ -441,25 +441,31 @@ static void wcnss_release_pds(struct qcom_wcnss *wcnss)
|
|||
}
|
||||
|
||||
static int wcnss_init_regulators(struct qcom_wcnss *wcnss,
|
||||
const struct wcnss_vreg_info *info,
|
||||
int num_vregs, int num_pd_vregs)
|
||||
const struct wcnss_data *data)
|
||||
{
|
||||
const struct wcnss_vreg_info *info = data->vregs;
|
||||
struct regulator_bulk_data *bulk;
|
||||
size_t i, possible_pds = 0, num_vregs = data->num_vregs;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < WCNSS_MAX_PDS; i++)
|
||||
if (data->pd_names[i])
|
||||
possible_pds++;
|
||||
|
||||
/*
|
||||
* If attaching the power domains suceeded we can skip requesting
|
||||
* the regulators for the power domains. For old device trees we need to
|
||||
* reserve extra space to manage them through the regulator interface.
|
||||
*/
|
||||
if (wcnss->num_pds) {
|
||||
if (possible_pds >= num_vregs) {
|
||||
/* Do nothing if vregs do not include PD regulators (pronto-v3) */
|
||||
} else if (wcnss->num_pds) {
|
||||
info += wcnss->num_pds;
|
||||
/* Handle single power domain case */
|
||||
if (wcnss->num_pds < num_pd_vregs)
|
||||
num_vregs += num_pd_vregs - wcnss->num_pds;
|
||||
if (wcnss->num_pds < data->num_pd_vregs)
|
||||
num_vregs += data->num_pd_vregs - wcnss->num_pds;
|
||||
} else {
|
||||
num_vregs += num_pd_vregs;
|
||||
num_vregs += data->num_pd_vregs;
|
||||
}
|
||||
|
||||
bulk = devm_kcalloc(wcnss->dev,
|
||||
|
|
@ -607,8 +613,7 @@ static int wcnss_probe(struct platform_device *pdev)
|
|||
if (ret && (ret != -ENODATA || !data->num_pd_vregs))
|
||||
return ret;
|
||||
|
||||
ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs,
|
||||
data->num_pd_vregs);
|
||||
ret = wcnss_init_regulators(wcnss, data);
|
||||
if (ret)
|
||||
goto detach_pds;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user