summaryrefslogtreecommitdiff
path: root/drivers/remoteproc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r--drivers/remoteproc/qcom_common.c14
-rw-r--r--drivers/remoteproc/qcom_q6v5_wcss.c23
-rw-r--r--drivers/remoteproc/xlnx_r5_remoteproc.c46
3 files changed, 51 insertions, 32 deletions
diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c
index fd2b6824ad26..e1a955476c9b 100644
--- a/drivers/remoteproc/qcom_common.c
+++ b/drivers/remoteproc/qcom_common.c
@@ -109,6 +109,7 @@ static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsy
struct minidump_region __iomem *ptr;
struct minidump_region region;
int seg_cnt, i;
+ int ret = 0;
dma_addr_t da;
size_t size;
char *name;
@@ -129,17 +130,22 @@ static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsy
if (le32_to_cpu(region.valid) == MINIDUMP_REGION_VALID) {
name = kstrndup(region.name, MAX_REGION_NAME_LENGTH - 1, GFP_KERNEL);
if (!name) {
- iounmap(ptr);
- return -ENOMEM;
+ ret = -ENOMEM;
+ break;
}
da = le64_to_cpu(region.address);
size = le64_to_cpu(region.size);
- rproc_coredump_add_custom_segment(rproc, da, size, rproc_dumpfn_t, name);
+ ret = rproc_coredump_add_custom_segment(rproc, da, size, rproc_dumpfn_t,
+ name);
+ if (ret) {
+ kfree(name);
+ break;
+ }
}
}
iounmap(ptr);
- return 0;
+ return ret;
}
void qcom_minidump(struct rproc *rproc, unsigned int minidump_id,
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index c27200159a88..b391724cfd08 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -96,7 +96,6 @@ struct wcss_data {
unsigned int crash_reason_smem;
u32 version;
bool aon_reset_required;
- bool wcss_q6_reset_required;
const char *ssr_name;
const char *sysmon_name;
int ssctl_id;
@@ -134,7 +133,6 @@ struct q6v5_wcss {
struct reset_control *wcss_aon_reset;
struct reset_control *wcss_reset;
struct reset_control *wcss_q6_reset;
- struct reset_control *wcss_q6_bcr_reset;
struct qcom_q6v5 q6v5;
@@ -309,7 +307,7 @@ static int q6v5_wcss_qcs404_power_on(struct q6v5_wcss *wcss)
return ret;
/* Remove reset to the WCNSS QDSP6SS */
- reset_control_deassert(wcss->wcss_q6_bcr_reset);
+ reset_control_deassert(wcss->wcss_q6_reset);
/* Enable Q6SSTOP_AHBFABRIC_CBCR clock */
ret = clk_prepare_enable(wcss->ahbfabric_cbcr_clk);
@@ -803,19 +801,10 @@ static int q6v5_wcss_init_reset(struct q6v5_wcss *wcss,
return PTR_ERR(wcss->wcss_reset);
}
- if (desc->wcss_q6_reset_required) {
- wcss->wcss_q6_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_reset");
- if (IS_ERR(wcss->wcss_q6_reset)) {
- dev_err(wcss->dev, "unable to acquire wcss_q6_reset\n");
- return PTR_ERR(wcss->wcss_q6_reset);
- }
- }
-
- wcss->wcss_q6_bcr_reset = devm_reset_control_get_optional_exclusive(dev,
- "wcss_q6_bcr_reset");
- if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
- dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
- return PTR_ERR(wcss->wcss_q6_bcr_reset);
+ wcss->wcss_q6_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_reset");
+ if (IS_ERR(wcss->wcss_q6_reset)) {
+ dev_err(wcss->dev, "unable to acquire wcss_q6_reset\n");
+ return PTR_ERR(wcss->wcss_q6_reset);
}
return 0;
@@ -1062,7 +1051,6 @@ static const struct wcss_data wcss_ipq8074_res_init = {
.firmware_name = "IPQ8074/q6_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
- .wcss_q6_reset_required = true,
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
};
@@ -1072,7 +1060,6 @@ static const struct wcss_data wcss_qcs404_res_init = {
.firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
.aon_reset_required = false,
- .wcss_q6_reset_required = false,
.ssr_name = "mpss",
.sysmon_name = "wcnss",
.ssctl_id = 0x12,
diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 50a9974f3202..45a62cb98072 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -948,16 +948,6 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
goto free_rproc;
}
- /*
- * If firmware is already available in the memory then move rproc state
- * to DETACHED. Firmware can be preloaded via debugger or by any other
- * agent (processors) in the system.
- * If firmware isn't available in the memory and resource table isn't
- * found, then rproc state remains OFFLINE.
- */
- if (!zynqmp_r5_get_rsc_table_va(r5_core))
- r5_rproc->state = RPROC_DETACHED;
-
r5_core->rproc = r5_rproc;
return r5_core;
@@ -1210,6 +1200,7 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
{
struct device *dev = cluster->dev;
struct zynqmp_r5_core *r5_core;
+ u32 req, usage, status;
int ret = -EINVAL, i;
r5_core = cluster->r5_cores[0];
@@ -1255,6 +1246,41 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
ret = zynqmp_r5_get_sram_banks(r5_core);
if (ret)
return ret;
+
+ /*
+ * It is possible that firmware is loaded into the memory, but
+ * RPU (remote) is not running. In such case, RPU state will be
+ * moved to RPROC_DETACHED wrongfully. To avoid it first make
+ * sure RPU is power-on and out of reset before parsing for the
+ * resource table.
+ */
+ ret = zynqmp_pm_get_rpu_node_status(r5_core->pm_domain_id,
+ &status, &req, &usage);
+ if (ret) {
+ dev_warn(r5_core->dev,
+ "failed to get rpu node status, err %d\n", ret);
+ continue;
+ }
+
+ /*
+ * If RPU state is power on and out of reset i.e. running, then
+ * assign RPROC_DETACHED state. If the RPU is not out of reset
+ * then do not attempt to attach to the remote processor.
+ */
+ if (status == PM_NODE_RUNNING) {
+ /*
+ * Not all the firmware that is running on the remote
+ * core is expected to have the resource table. The
+ * firmware might not use RPMsg at all, and in that case
+ * resource table becomes irrelevant. However, we still
+ * need to make sure that running core is not reported
+ * as offline. so do not decide remote core state based
+ * on the resource table availability
+ */
+ if (zynqmp_r5_get_rsc_table_va(r5_core))
+ dev_dbg(r5_core->dev, "rsc tbl not found\n");
+ r5_core->rproc->state = RPROC_DETACHED;
+ }
}
return 0;