summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-09-22 10:12:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-09-22 10:12:54 -0700
commit34e34736ea9a685664f57586f6e293aaff308858 (patch)
treebc2d960952590b447a19dc8ab69df13172581009
parentc4e9f74da4389a6b3e505d329d99232915a6b9cd (diff)
parent9db31edf92dde1f3c98008bd5f88e859d14324cc (diff)
Merge tag 'rproc-v7.3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux
Pull remoteproc fixes from Bjorn Andersson: "Fix unbalanced handover IRQ on attach and the overwriting of the shutdown return value in the Qualcomm PAS remoteproc driver. Correct the conditions in the Qualcomm modem remoteproc driver for which secure services to require after the move to 'PAS service'. Ensure that the correct addresses are passed to iommu_unmap() as Qualcomm ADSP carveout are torn down" * tag 'rproc-v7.3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: remoteproc: qcom_q6v5_pas: Fix error masking in qcom_pas_stop() remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage remoteproc: qcom_q6v5_mss: Don't require PAS for memory protection remoteproc: qcom: q6v5_pas: Don't enable handover IRQ on attach
-rw-r--r--drivers/remoteproc/qcom_q6v5_adsp.c8
-rw-r--r--drivers/remoteproc/qcom_q6v5_mss.c11
-rw-r--r--drivers/remoteproc/qcom_q6v5_pas.c12
3 files changed, 21 insertions, 10 deletions
diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
index 39654206781d..2e5fb5954fa9 100644
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -104,6 +104,7 @@ struct qcom_adsp {
struct completion stop_done;
phys_addr_t mem_phys;
+ unsigned long iova;
phys_addr_t mem_reloc;
void __iomem *mem_region;
size_t mem_size;
@@ -333,7 +334,7 @@ static void adsp_unmap_carveout(struct rproc *rproc)
struct qcom_adsp *adsp = rproc->priv;
if (adsp->has_iommu)
- iommu_unmap(rproc->domain, adsp->mem_phys, adsp->mem_size);
+ iommu_unmap(rproc->domain, adsp->iova, adsp->mem_size);
}
static int adsp_map_carveout(struct rproc *rproc)
@@ -341,7 +342,6 @@ static int adsp_map_carveout(struct rproc *rproc)
struct qcom_adsp *adsp = rproc->priv;
struct of_phandle_args args;
long long sid;
- unsigned long iova;
int ret;
if (!adsp->has_iommu)
@@ -358,9 +358,9 @@ static int adsp_map_carveout(struct rproc *rproc)
of_node_put(args.np);
/* Add SID configuration for ADSP Firmware to SMMU */
- iova = adsp->mem_phys | (sid << 32);
+ adsp->iova = adsp->mem_phys | (sid << 32);
- ret = iommu_map(rproc->domain, iova, adsp->mem_phys,
+ ret = iommu_map(rproc->domain, adsp->iova, adsp->mem_phys,
adsp->mem_size, IOMMU_READ | IOMMU_WRITE,
GFP_KERNEL);
if (ret) {
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index bef198b9ee63..2f71ed2feff6 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -2079,7 +2079,16 @@ static int q6v5_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
- if (desc->need_mem_protection && !qcom_pas_is_available())
+ /*
+ * Memory protection is done through qcom_scm_assign_mem(), which needs
+ * SCM but not PAS. Only the memory setup path issues PAS calls, so
+ * requiring PAS for every need_mem_protection platform prevents the
+ * modem from probing at all on TZ firmware that offers no PAS.
+ */
+ if (desc->need_mem_protection && !qcom_scm_is_available())
+ return -EPROBE_DEFER;
+
+ if (desc->need_pas_mem_setup && !qcom_pas_is_available())
return -EPROBE_DEFER;
mba_image = desc->hexagon_mba_image;
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index ca8e61254c44..a005546c265d 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -405,6 +405,7 @@ static int qcom_pas_stop(struct rproc *rproc)
{
struct qcom_pas *pas = rproc->priv;
int handover;
+ int dtb_ret;
int ret;
ret = qcom_q6v5_request_stop(&pas->q6v5, pas->sysmon);
@@ -419,9 +420,12 @@ static int qcom_pas_stop(struct rproc *rproc)
dev_err(pas->dev, "failed to shutdown: %d\n", ret);
if (pas->dtb_pas_id) {
- ret = qcom_pas_shutdown(pas->dtb_pas_id);
- if (ret)
- dev_err(pas->dev, "failed to shutdown dtb: %d\n", ret);
+ dtb_ret = qcom_pas_shutdown(pas->dtb_pas_id);
+ if (dtb_ret)
+ dev_err(pas->dev, "failed to shutdown dtb: %d\n", dtb_ret);
+
+ if (!ret && dtb_ret)
+ ret = dtb_ret;
qcom_pas_unmap_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size);
}
@@ -524,7 +528,6 @@ static int qcom_pas_attach(struct rproc *rproc)
int ret;
pas->q6v5.handover_issued = true;
- enable_irq(pas->q6v5.handover_irq);
pas->q6v5.running = true;
ret = irq_get_irqchip_state(pas->q6v5.fatal_irq,
@@ -570,7 +573,6 @@ unroll_attach:
pas->rproc->state = RPROC_OFFLINE;
ret = -EINVAL;
disable_running:
- disable_irq(pas->q6v5.handover_irq);
pas->q6v5.running = false;
return ret;