diff options
author | qctecmdr <qctecmdr@localhost> | 2020-07-14 05:45:51 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2020-07-14 05:45:51 -0700 |
commit | ebfe8dd23f85146ce8ec45ecaaf858c9e3969803 (patch) | |
tree | c02931e1392f86d950993b40191ed77085c93616 | |
parent | f813d50dc4db8936dcde05ac1fe2d564e590be9d (diff) | |
parent | 4744ed702bae3b6c6fa8c59e617631f954eea566 (diff) | |
download | msm-extra-ebfe8dd23f85146ce8ec45ecaaf858c9e3969803.tar.gz |
Merge "dsp: Fix a memory leak issue when nvmem read returns invalid length"
-rw-r--r-- | dsp/adsp-loader.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 8316f003..e99d6a3c 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2014, 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017-2020, The Linux Foundation. All rights reserved. */ #include <linux/init.h> @@ -333,6 +333,8 @@ static int adsp_loader_probe(struct platform_device *pdev) int fw_name_size; u32 adsp_var_idx = 0; int ret = 0; + u32 adsp_fuse_not_supported = 0; + const char *adsp_fw_name; ret = adsp_loader_init_sysfs(pdev); if (ret != 0) { @@ -344,15 +346,58 @@ static int adsp_loader_probe(struct platform_device *pdev) /* get adsp variant idx */ cell = nvmem_cell_get(&pdev->dev, "adsp_variant"); if (IS_ERR_OR_NULL(cell)) { - dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__); + dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", + __func__); + + /* + * When ADSP variant read from fuse register is not + * supported, check if image with different fw image + * name needs to be loaded + */ + ret = of_property_read_u32(pdev->dev.of_node, + "adsp-fuse-not-supported", + &adsp_fuse_not_supported); + if (ret) { + dev_dbg(&pdev->dev, + "%s: adsp_fuse_not_supported prop not found", + __func__, ret); + goto wqueue; + } + + if (adsp_fuse_not_supported) { + /* Read ADSP firmware image name */ + ret = of_property_read_string(pdev->dev.of_node, + "adsp-fw-name", + &adsp_fw_name); + if (ret < 0) { + dev_dbg(&pdev->dev, "%s: unable to read fw-name\n", + __func__); + goto wqueue; + } + + fw_name_size = strlen(adsp_fw_name) + 1; + priv->adsp_fw_name = devm_kzalloc(&pdev->dev, + fw_name_size, + GFP_KERNEL); + if (!priv->adsp_fw_name) + goto wqueue; + strlcpy(priv->adsp_fw_name, adsp_fw_name, + fw_name_size); + } goto wqueue; } buf = nvmem_cell_read(cell, &len); nvmem_cell_put(cell); - if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(u32)) { + if (IS_ERR_OR_NULL(buf)) { dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__); goto wqueue; } + if (len <= 0 || len > sizeof(u32)) { + dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n", + __func__, len); + kfree(buf); + goto wqueue; + } memcpy(&adsp_var_idx, buf, len); kfree(buf); |