diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index fd1d70d1d4d7..62cc30d88bd8 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -72,7 +72,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) goto err_release_fw; } - ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL); + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, NULL); qcom_scm_pas_metadata_release(ctx); if (ret) goto err_mem_unmap; diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index c69df8edde8f..0cf8cbbbbb3f 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -100,8 +100,9 @@ struct qcom_pas { phys_addr_t mem_reloc; phys_addr_t dtb_mem_reloc; phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT]; + void *mem_region; - void *dtb_mem_region; + size_t mem_size; size_t dtb_mem_size; size_t region_assign_size[MAX_ASSIGN_COUNT]; @@ -148,7 +149,16 @@ static void qcom_pas_minidump(struct rproc *rproc) if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) return; + pas->mem_region = ioremap_wc(pas->mem_phys, pas->mem_size); + if (!pas->mem_region) { + dev_err(pas->dev, "unable to map memory region: %pa+%zx\n", + &pas->mem_phys, pas->mem_size); + 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, @@ -253,7 +263,7 @@ 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_firmware_name, &pas->dtb_mem_reloc); if (ret) goto release_dtb_metadata; @@ -262,7 +272,9 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) return 0; release_dtb_metadata: - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); + if (pas->dtb_pas_id) + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx); + release_firmware(pas->dtb_firmware); return ret; @@ -331,7 +343,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; @@ -522,6 +534,22 @@ static unsigned long qcom_pas_panic(struct rproc *rproc) return qcom_q6v5_panic(&pas->q6v5); } +static void qcom_pas_coredump(struct rproc *rproc) +{ + struct qcom_pas *pas = rproc->priv; + + pas->mem_region = ioremap_wc(pas->mem_phys, pas->mem_size); + if (!pas->mem_region) { + dev_err(pas->dev, "unable to map memory region: %pa+%zx\n", + &pas->mem_phys, pas->mem_size); + 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, @@ -530,6 +558,7 @@ static const struct rproc_ops qcom_pas_ops = { .parse_fw = qcom_pas_parse_firmware, .load = qcom_pas_load, .panic = qcom_pas_panic, + .coredump = qcom_pas_coredump, }; static const struct rproc_ops qcom_pas_minidump_ops = { @@ -635,6 +664,7 @@ static void qcom_pas_pds_detach(struct qcom_pas *pas, struct device **pds, size_ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) { + struct rproc *rproc = pas->rproc; struct reserved_mem *rmem; struct device_node *node; @@ -653,13 +683,12 @@ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) pas->mem_phys = pas->mem_reloc = rmem->base; pas->mem_size = rmem->size; - pas->mem_region = devm_ioremap_wc(pas->dev, pas->mem_phys, pas->mem_size); - if (!pas->mem_region) { - dev_err(pas->dev, "unable to map memory region: %pa+%zx\n", - &rmem->base, pas->mem_size); - return -EBUSY; - } + pas->pas_ctx = devm_qcom_scm_pas_context_alloc(pas->dev, pas->pas_id, + pas->mem_phys, pas->mem_size); + if (IS_ERR(pas->pas_ctx)) + return PTR_ERR(pas->pas_ctx); + pas->pas_ctx->use_tzmem = rproc->has_iommu; if (!pas->dtb_pas_id) return 0; @@ -678,12 +707,13 @@ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) pas->dtb_mem_phys = pas->dtb_mem_reloc = rmem->base; pas->dtb_mem_size = rmem->size; - pas->dtb_mem_region = devm_ioremap_wc(pas->dev, pas->dtb_mem_phys, pas->dtb_mem_size); - if (!pas->dtb_mem_region) { - dev_err(pas->dev, "unable to map dtb memory region: %pa+%zx\n", - &rmem->base, pas->dtb_mem_size); - return -EBUSY; - } + pas->dtb_pas_ctx = devm_qcom_scm_pas_context_alloc(pas->dev, pas->dtb_pas_id, + pas->dtb_mem_phys, + pas->dtb_mem_size); + if (IS_ERR(pas->dtb_pas_ctx)) + return PTR_ERR(pas->dtb_pas_ctx); + + pas->dtb_pas_ctx->use_tzmem = rproc->has_iommu; return 0; } @@ -869,23 +899,6 @@ static int qcom_pas_probe(struct platform_device *pdev) qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name); - pas->pas_ctx = devm_qcom_scm_pas_context_alloc(pas->dev, pas->pas_id, - pas->mem_phys, pas->mem_size); - if (IS_ERR(pas->pas_ctx)) { - ret = PTR_ERR(pas->pas_ctx); - goto remove_ssr_sysmon; - } - - pas->dtb_pas_ctx = devm_qcom_scm_pas_context_alloc(pas->dev, pas->dtb_pas_id, - pas->dtb_mem_phys, - pas->dtb_mem_size); - if (IS_ERR(pas->dtb_pas_ctx)) { - ret = PTR_ERR(pas->dtb_pas_ctx); - goto remove_ssr_sysmon; - } - - pas->pas_ctx->use_tzmem = rproc->has_iommu; - pas->dtb_pas_ctx->use_tzmem = rproc->has_iommu; ret = rproc_add(rproc); if (ret) goto remove_ssr_sysmon; diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index 1ca03472552c..3936839da329 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 @@ -486,22 +487,31 @@ EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init); * @ctx: Pointer to the PAS (Peripheral Authentication Service) context * @fw: Firmware object representing the .mdt file * @firmware: Name of the firmware used to construct segment file names - * @mem_region: Memory region allocated for loading the firmware * @reloc_base: Physical address adjusted after relocation * * Return: 0 on success or a negative error code on failure. */ int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw, - const char *firmware, void *mem_region, phys_addr_t *reloc_base) + const char *firmware, phys_addr_t *reloc_base) { + void *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, mem_region, ctx->mem_phys, - ctx->mem_size, reloc_base); + mem_region = ioremap_wc(ctx->mem_phys, ctx->mem_size); + if (!mem_region) { + dev_err(ctx->dev, "unable to map memory region: %pa+%zx\n", &ctx->mem_phys, + ctx->mem_size); + return -EINVAL; + } + + ret = qcom_mdt_load_no_init(ctx->dev, fw, firmware, 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/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h index 82372e0db0a1..7c551b98e182 100644 --- a/include/linux/soc/qcom/mdt_loader.h +++ b/include/linux/soc/qcom/mdt_loader.h @@ -21,7 +21,7 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, phys_addr_t *reloc_base); int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw, - const char *firmware, void *mem_region, phys_addr_t *reloc_base); + const char *firmware, phys_addr_t *reloc_base); int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, const char *fw_name, void *mem_region, @@ -47,7 +47,7 @@ static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw, static inline int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw, const char *firmware, - void *mem_region, phys_addr_t *reloc_base) + phys_addr_t *reloc_base) { return -ENODEV; }