diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 76e345acf666..4273992dec56 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -147,7 +147,13 @@ static void qcom_pas_minidump(struct rproc *rproc) if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) return; + pas->mem_region = qcom_pas_ctx_map(pas->pas_ctx); + if (!pas->mem_region) + return; + qcom_minidump(rproc, pas->minidump_id, qcom_pas_segment_dump); + iounmap(pas->mem_region); + pas->mem_region = NULL; } static int qcom_pas_pds_enable(struct qcom_pas *pas, struct device **pds, @@ -240,10 +246,12 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) } ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, - pas->dtb_firmware_name, pas->dtb_mem_region, - &pas->dtb_mem_reloc); - if (ret) - goto release_dtb_metadata; + pas->dtb_firmware_name, &pas->dtb_mem_reloc); + if (ret) { + qcom_pas_metadata_release(pas->dtb_pas_ctx); + release_firmware(pas->dtb_firmware); + return ret; + } } return 0; @@ -318,7 +326,7 @@ static int qcom_pas_start(struct rproc *rproc) } ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware, - pas->mem_region, &pas->mem_reloc); + &pas->mem_reloc); if (ret) goto release_pas_metadata; @@ -560,6 +568,19 @@ disable_running: return ret; } +static void qcom_pas_coredump(struct rproc *rproc) +{ + struct qcom_pas *pas = rproc->priv; + + pas->mem_region = qcom_pas_ctx_map(pas->pas_ctx); + if (!pas->mem_region) + return; + + rproc_coredump(rproc); + iounmap(pas->mem_region); + pas->mem_region = NULL; +} + static const struct rproc_ops qcom_pas_ops = { .unprepare = qcom_pas_unprepare, .start = qcom_pas_start, @@ -569,6 +590,7 @@ static const struct rproc_ops qcom_pas_ops = { .load = qcom_pas_load, .panic = qcom_pas_panic, .attach = qcom_pas_attach, + .coredump = qcom_pas_coredump, }; static const struct rproc_ops qcom_pas_minidump_ops = { @@ -686,11 +708,6 @@ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) pas->mem_phys = pas->mem_reloc = res.start; pas->mem_size = resource_size(&res); - pas->mem_region = devm_ioremap_resource_wc(pas->dev, &res); - if (IS_ERR(pas->mem_region)) { - dev_err(pas->dev, "unable to map memory region: %pR\n", &res); - return PTR_ERR(pas->mem_region); - } if (!pas->dtb_pas_id) return 0; @@ -703,11 +720,6 @@ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) pas->dtb_mem_phys = pas->dtb_mem_reloc = res.start; pas->dtb_mem_size = resource_size(&res); - pas->dtb_mem_region = devm_ioremap_resource_wc(pas->dev, &res); - if (IS_ERR(pas->dtb_mem_region)) { - dev_err(pas->dev, "unable to map dtb memory region: %pR\n", &res); - return PTR_ERR(pas->dtb_mem_region); - } return 0; } diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index 4ebe5100dc71..002100fe2d32 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -485,14 +486,21 @@ EXPORT_SYMBOL_GPL(qcom_mdt_load); int qcom_mdt_pas_load(struct qcom_pas_context *ctx, const struct firmware *fw, const char *firmware, phys_addr_t *reloc_base) { + void __iomem *mem_region; int ret; ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys, ctx); if (ret) return ret; - return qcom_mdt_load_no_init(ctx->dev, fw, firmware, ctx->ptr, ctx->mem_phys, - ctx->mem_size, reloc_base); + mem_region = qcom_pas_ctx_map(ctx); + if (!mem_region) + return -ENOMEM; + + ret = qcom_mdt_load_no_init(ctx->dev, fw, firmware, (__force void *)mem_region, + ctx->mem_phys, ctx->mem_size, reloc_base); + iounmap(mem_region); + return ret; } EXPORT_SYMBOL_GPL(qcom_mdt_pas_load); diff --git a/include/linux/firmware/qcom/qcom_pas.h b/include/linux/firmware/qcom/qcom_pas.h index 65b1c9564458..fb2ec3be6a16 100644 --- a/include/linux/firmware/qcom/qcom_pas.h +++ b/include/linux/firmware/qcom/qcom_pas.h @@ -8,7 +8,9 @@ #ifndef __QCOM_PAS_H #define __QCOM_PAS_H +#include #include +#include #include struct qcom_pas_context { @@ -22,6 +24,16 @@ struct qcom_pas_context { bool use_tzmem; }; +static inline void __iomem *qcom_pas_ctx_map(struct qcom_pas_context *ctx) +{ + void __iomem *ptr = ioremap_wc(ctx->mem_phys, ctx->mem_size); + + if (!ptr) + dev_err(ctx->dev, "unable to map memory region: %pa+%zx\n", + &ctx->mem_phys, ctx->mem_size); + return ptr; +} + bool qcom_pas_is_available(void); struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev, u32 pas_id,