From 665a61b298cd26e78a5dda6520834c428ec65e9b Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Wed, 12 Aug 2026 14:15:20 +0530 Subject: [PATCH 1/4] PENDING: arm64: dts: qcom: nord: Add PMU node Add the top-level pmu node so perf events can be collected on Nord. Signed-off-by: Anurag Pateriya --- arch/arm64/boot/dts/qcom/nord.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/nord.dtsi b/arch/arm64/boot/dts/qcom/nord.dtsi index ade030a45f87..92d486c8033d 100644 --- a/arch/arm64/boot/dts/qcom/nord.dtsi +++ b/arch/arm64/boot/dts/qcom/nord.dtsi @@ -398,6 +398,11 @@ reg = <0x0 0x80000000 0x0 0x0>; }; + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; From a4728db9d8438f56d1d77bc52aab8f6a10c0f04e Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Wed, 12 Aug 2026 14:16:12 +0530 Subject: [PATCH 2/4] PENDING: arm64: dts: qcom: nord: Add reboot-mode for EDL and bootloader Add the reboot-mode node under psci with vendor-specific SYSTEM_RESET2 parameters for EDL and bootloader. This lets userspace request "reboot bootloader" and "reboot edl" via the standard reboot-mode framework. Signed-off-by: Anurag Pateriya --- arch/arm64/boot/dts/qcom/nord.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/nord.dtsi b/arch/arm64/boot/dts/qcom/nord.dtsi index 92d486c8033d..4ae7fbff2244 100644 --- a/arch/arm64/boot/dts/qcom/nord.dtsi +++ b/arch/arm64/boot/dts/qcom/nord.dtsi @@ -537,6 +537,11 @@ #power-domain-cells = <0>; domain-idle-states = <&domain_ss3>; }; + + reboot-mode { + mode-bootloader = <0x80010001 0x2>; + mode-edl = <0x80000000 0x1>; + }; }; reserved_memory: reserved-memory { From c38f7cf8d0abb5c1f0ee0bd93bc7a1a10ad25ecf Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Wed, 12 Aug 2026 16:52:29 +0530 Subject: [PATCH 3/4] Revert "FROMGIT: remoteproc: qcom: pas: Add late attach support for subsystems" This reverts commit 74b4253005769661593b65d6aff64b59c1ace836. Reverting this to update to latest version. Signed-off-by: Anurag Pateriya --- drivers/remoteproc/qcom_common.h | 6 ----- drivers/remoteproc/qcom_q6v5.c | 3 +-- drivers/remoteproc/qcom_q6v5_pas.c | 36 ++++++++++++++---------------- drivers/remoteproc/qcom_sysmon.c | 19 ---------------- 4 files changed, 18 insertions(+), 46 deletions(-) diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index b0e7e336d363..b07fbaa091a0 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -68,7 +68,6 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, int ssctl_instance); void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon); bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon); -bool qcom_sysmon_shutdown_irq_state(struct qcom_sysmon *sysmon); #else static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, const char *name, @@ -85,11 +84,6 @@ static inline bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon) { return false; } - -static inline bool qcom_sysmon_shutdown_irq_state(struct qcom_sysmon *sysmon) -{ - return false; -} #endif #endif diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c index 99e4384f1b0e..fc63e13bd909 100644 --- a/drivers/remoteproc/qcom_q6v5.c +++ b/drivers/remoteproc/qcom_q6v5.c @@ -235,8 +235,7 @@ int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5, struct qcom_sysmon *sysmon) q6v5->running = false; /* Don't perform SMP2P dance if remote isn't running */ - if ((q6v5->rproc->state != RPROC_RUNNING && q6v5->rproc->state != RPROC_ATTACHED) || - qcom_sysmon_shutdown_acked(sysmon)) + if (q6v5->rproc->state != RPROC_RUNNING || qcom_sysmon_shutdown_acked(sysmon)) return 0; qcom_smem_state_update_bits(q6v5->state, diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 0ca373a29462..3a30cbd3ce2b 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -561,17 +561,15 @@ static void qcom_pas_coredump(struct rproc *rproc) static int qcom_pas_attach(struct rproc *rproc) { + int ret; struct qcom_pas *pas = rproc->priv; bool ready_state; bool crash_state; - bool stop_state; - int ret; - - pas->q6v5.handover_issued = true; pas->q6v5.running = true; ret = irq_get_irqchip_state(pas->q6v5.fatal_irq, IRQCHIP_STATE_LINE_LEVEL, &crash_state); + if (ret) goto disable_running; @@ -582,18 +580,9 @@ static int qcom_pas_attach(struct rproc *rproc) goto disable_running; } - ret = irq_get_irqchip_state(pas->q6v5.stop_irq, - IRQCHIP_STATE_LINE_LEVEL, &stop_state); - if (ret) - goto disable_running; - - if (stop_state || qcom_sysmon_shutdown_irq_state(pas->sysmon)) { - dev_info(pas->dev, "Subsystem found stop state set. Falling back to start.\n"); - goto unroll_attach; - } - ret = irq_get_irqchip_state(pas->q6v5.ready_irq, IRQCHIP_STATE_LINE_LEVEL, &ready_state); + if (ret) goto disable_running; @@ -604,14 +593,23 @@ static int qcom_pas_attach(struct rproc *rproc) * start the remoteproc. */ dev_err(pas->dev, "Failed to get subsystem ready interrupt\n"); - goto unroll_attach; + pas->rproc->state = RPROC_OFFLINE; + ret = -EINVAL; + goto disable_running; + } + + ret = qcom_q6v5_ping_subsystem(&pas->q6v5); + + if (ret) { + dev_err(pas->dev, "Failed to ping subsystem, assuming device crashed\n"); + rproc_report_crash(rproc, RPROC_FATAL_ERROR); + goto disable_running; } + pas->q6v5.handover_issued = true; + return 0; -unroll_attach: - pas->rproc->state = RPROC_OFFLINE; - ret = -EINVAL; disable_running: pas->q6v5.running = false; @@ -639,7 +637,6 @@ static const struct rproc_ops qcom_pas_minidump_ops = { .load = qcom_pas_load, .panic = qcom_pas_panic, .coredump = qcom_pas_minidump, - .attach = qcom_pas_attach, }; static int qcom_pas_init_clock(struct qcom_pas *pas) @@ -1023,6 +1020,7 @@ static int qcom_pas_probe(struct platform_device *pdev) pas->rproc->state = RPROC_DETACHED; } + ret = qcom_pas_setup_tmd(pas); if (ret) goto remove_ssr_sysmon; diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c index a0830a48b1f4..913e3b750a86 100644 --- a/drivers/remoteproc/qcom_sysmon.c +++ b/drivers/remoteproc/qcom_sysmon.c @@ -736,25 +736,6 @@ bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon) } EXPORT_SYMBOL_GPL(qcom_sysmon_shutdown_acked); -bool qcom_sysmon_shutdown_irq_state(struct qcom_sysmon *sysmon) -{ - bool shutdown_state; - int ret; - - if (!sysmon) - return false; - - ret = irq_get_irqchip_state(sysmon->shutdown_irq, - IRQCHIP_STATE_LINE_LEVEL, &shutdown_state); - if (ret) { - dev_warn(sysmon->dev, "failed to get shutdown_state: %d\n", ret); - return false; - } - - return shutdown_state; -} -EXPORT_SYMBOL_GPL(qcom_sysmon_shutdown_irq_state); - /** * sysmon_probe() - probe sys_mon channel * @rpdev: rpmsg device handle From 0076c72119128b8abe8aabe1dd29f70197c9fdc3 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Tue, 23 Jun 2026 03:05:21 -0700 Subject: [PATCH 4/4] FROMGIT: remoteproc: qcom: pas: Add late attach support for subsystems Subsystems can be brought out of reset by entities such as bootloaders. As the irq enablement could be later than subsystem bring up, the state of subsystem should be checked by reading SMP2P bits. A new qcom_pas_attach() function is introduced. if crash state is detected for the subsystem, rproc_report_crash() is called. If the ready state is detected meanwhile stop state is not detected, it will be marked as "attached", otherwise it could be the early boot feature is not supported by other entities or it has already been stopped. In above cases, the state will be marked as RPROC_OFFLINE so that the PAS driver can load the firmware and start the remoteproc. Co-developed-by: Gokul Krishna Krishnakumar Signed-off-by: Gokul Krishna Krishnakumar Tested-by: Shawn Guo Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/r/20260623-knp-soccp-v7-5-1ec7bb5c9fec@oss.qualcomm.com Signed-off-by: Anurag Pateriya --- drivers/remoteproc/qcom_common.h | 6 ++++ drivers/remoteproc/qcom_q6v5.c | 3 +- drivers/remoteproc/qcom_q6v5_pas.c | 45 ++++++++++++++---------------- drivers/remoteproc/qcom_sysmon.c | 19 +++++++++++++ 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index b07fbaa091a0..b0e7e336d363 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -68,6 +68,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, int ssctl_instance); void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon); bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon); +bool qcom_sysmon_shutdown_irq_state(struct qcom_sysmon *sysmon); #else static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, const char *name, @@ -84,6 +85,11 @@ static inline bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon) { return false; } + +static inline bool qcom_sysmon_shutdown_irq_state(struct qcom_sysmon *sysmon) +{ + return false; +} #endif #endif diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c index fc63e13bd909..99e4384f1b0e 100644 --- a/drivers/remoteproc/qcom_q6v5.c +++ b/drivers/remoteproc/qcom_q6v5.c @@ -235,7 +235,8 @@ int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5, struct qcom_sysmon *sysmon) q6v5->running = false; /* Don't perform SMP2P dance if remote isn't running */ - if (q6v5->rproc->state != RPROC_RUNNING || qcom_sysmon_shutdown_acked(sysmon)) + if ((q6v5->rproc->state != RPROC_RUNNING && q6v5->rproc->state != RPROC_ATTACHED) || + qcom_sysmon_shutdown_acked(sysmon)) return 0; qcom_smem_state_update_bits(q6v5->state, diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 3a30cbd3ce2b..37084a038c51 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -561,15 +561,17 @@ static void qcom_pas_coredump(struct rproc *rproc) static int qcom_pas_attach(struct rproc *rproc) { - int ret; struct qcom_pas *pas = rproc->priv; bool ready_state; bool crash_state; + bool stop_state; + int ret; + + pas->q6v5.handover_issued = true; pas->q6v5.running = true; ret = irq_get_irqchip_state(pas->q6v5.fatal_irq, IRQCHIP_STATE_LINE_LEVEL, &crash_state); - if (ret) goto disable_running; @@ -580,9 +582,18 @@ static int qcom_pas_attach(struct rproc *rproc) goto disable_running; } + ret = irq_get_irqchip_state(pas->q6v5.stop_irq, + IRQCHIP_STATE_LINE_LEVEL, &stop_state); + if (ret) + goto disable_running; + + if (stop_state || qcom_sysmon_shutdown_irq_state(pas->sysmon)) { + dev_info(pas->dev, "Subsystem found stop state set. Falling back to start.\n"); + goto unroll_attach; + } + ret = irq_get_irqchip_state(pas->q6v5.ready_irq, IRQCHIP_STATE_LINE_LEVEL, &ready_state); - if (ret) goto disable_running; @@ -593,23 +604,14 @@ static int qcom_pas_attach(struct rproc *rproc) * start the remoteproc. */ dev_err(pas->dev, "Failed to get subsystem ready interrupt\n"); - pas->rproc->state = RPROC_OFFLINE; - ret = -EINVAL; - goto disable_running; + goto unroll_attach; } - ret = qcom_q6v5_ping_subsystem(&pas->q6v5); - - if (ret) { - dev_err(pas->dev, "Failed to ping subsystem, assuming device crashed\n"); - rproc_report_crash(rproc, RPROC_FATAL_ERROR); - goto disable_running; - } - - pas->q6v5.handover_issued = true; - return 0; +unroll_attach: + pas->rproc->state = RPROC_OFFLINE; + ret = -EINVAL; disable_running: pas->q6v5.running = false; @@ -637,6 +639,7 @@ static const struct rproc_ops qcom_pas_minidump_ops = { .load = qcom_pas_load, .panic = qcom_pas_panic, .coredump = qcom_pas_minidump, + .attach = qcom_pas_attach, }; static int qcom_pas_init_clock(struct qcom_pas *pas) @@ -1012,14 +1015,8 @@ static int qcom_pas_probe(struct platform_device *pdev) pas->pas_ctx->use_tzmem = desc->needs_tzmem || rproc->has_iommu; pas->dtb_pas_ctx->use_tzmem = desc->needs_tzmem || rproc->has_iommu; - if (desc->early_boot) { - ret = qcom_q6v5_ping_subsystem_init(&pas->q6v5, pdev); - if (ret) - dev_warn(&pdev->dev, "Falling back to firmware load\n"); - else - pas->rproc->state = RPROC_DETACHED; - } - + if (desc->early_boot) + pas->rproc->state = RPROC_DETACHED; ret = qcom_pas_setup_tmd(pas); if (ret) diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c index 913e3b750a86..a0830a48b1f4 100644 --- a/drivers/remoteproc/qcom_sysmon.c +++ b/drivers/remoteproc/qcom_sysmon.c @@ -736,6 +736,25 @@ bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon) } EXPORT_SYMBOL_GPL(qcom_sysmon_shutdown_acked); +bool qcom_sysmon_shutdown_irq_state(struct qcom_sysmon *sysmon) +{ + bool shutdown_state; + int ret; + + if (!sysmon) + return false; + + ret = irq_get_irqchip_state(sysmon->shutdown_irq, + IRQCHIP_STATE_LINE_LEVEL, &shutdown_state); + if (ret) { + dev_warn(sysmon->dev, "failed to get shutdown_state: %d\n", ret); + return false; + } + + return shutdown_state; +} +EXPORT_SYMBOL_GPL(qcom_sysmon_shutdown_irq_state); + /** * sysmon_probe() - probe sys_mon channel * @rpdev: rpmsg device handle