* [PATCH] remoteproc: xlnx: check remote node state
@ 2026-04-25 3:02 Tanmay Shah
2026-04-25 3:51 ` Padhi, Beleswar
0 siblings, 1 reply; 5+ messages in thread
From: Tanmay Shah @ 2026-04-25 3:02 UTC (permalink / raw)
To: michal.simek, andersson, mathieu.poirier
Cc: linux-arm-kernel, linux-kernel, linux-remoteproc, Tanmay Shah
The remote state is set to RPROC_DETACHED if the resource table is found
in the memory. However, this can be wrong if the remote is not started,
but firmware is still loaded in the memory. Use PM_GET_NODE_STATUS call
to the firmware to request the state of the RPU node. If the RPU is
actually out of reset and running, only then move the remote state to
RPROC_DETACHED, otherwise keep the remote state to RPROC_OFFLINE.
Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
---
drivers/firmware/xilinx/zynqmp.c | 28 +++++++++++++++++++
drivers/remoteproc/xlnx_r5_remoteproc.c | 37 ++++++++++++++++++-------
include/linux/firmware/xlnx-zynqmp.h | 21 ++++++++++++++
3 files changed, 76 insertions(+), 10 deletions(-)
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index fbe8510f4927..af838b2dc327 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1450,6 +1450,34 @@ int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
}
EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status);
+/**
+ * zynqmp_pm_get_rpu_node_status - PM call to request a RPU node's current power state
+ * @node: ID of the RPU component or sub-system in question
+ * @status: Current operating state of the requested RPU node.
+ * @requirements: Current requirements asserted on the RPU node.
+ * @usage: Usage information, used for RPU slave nodes only:
+ * PM_USAGE_NO_MASTER - No master is currently using
+ * the node
+ * PM_USAGE_CURRENT_MASTER - Only requesting master is
+ * currently using the node
+ * PM_USAGE_OTHER_MASTER - Only other masters are
+ * currently using the node
+ * PM_USAGE_BOTH_MASTERS - Both the current and at least
+ * one other master is currently
+ * using the node
+ *
+ * Return: Returns status, either success or error+reason
+ */
+int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
+ u32 *const requirements, u32 *const usage)
+{
+ if (zynqmp_pm_feature(PM_GET_NODE_STATUS) < PM_API_VERSION_2)
+ return -EOPNOTSUPP;
+
+ return zynqmp_pm_get_node_status(node, status, requirements, usage);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_node_status);
+
/**
* zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to
* be powered down forcefully
diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 50a9974f3202..e2f25d94177d 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,32 @@ 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) {
+ 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;
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index d70dcd462b44..7e27b0f7bf7e 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -542,6 +542,18 @@ enum pm_gem_config_type {
GEM_CONFIG_FIXED = 2,
};
+/**
+ * enum pm_node_status - Device node status provided by xilpm fw
+ * @PM_NODE_UNUSED: Device is not used
+ * @PM_NODE_RUNNING: Device is power-on and out of reset
+ * @PM_NODE_HALT: Device is power-on but in the reset state
+ */
+enum pm_node_status {
+ PM_NODE_UNUSED = 0,
+ PM_NODE_RUNNING = 1,
+ PM_NODE_HALT = 12,
+};
+
/**
* struct zynqmp_pm_query_data - PM query data
* @qid: query ID
@@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode);
int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
u32 *const requirements, u32 *const usage);
+int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
+ u32 *const requirements, u32 *const usage);
int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
u32 value);
@@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
return -ENODEV;
}
+static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
+ u32 *const requirements,
+ u32 *const usage)
+{
+ return -ENODEV;
+}
+
static inline int zynqmp_pm_set_sd_config(u32 node,
enum pm_sd_config_type config,
u32 value)
base-commit: 6f860d238b44da8ac57be25289b9f4410691c4e2
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] remoteproc: xlnx: check remote node state
2026-04-25 3:02 [PATCH] remoteproc: xlnx: check remote node state Tanmay Shah
@ 2026-04-25 3:51 ` Padhi, Beleswar
2026-04-27 16:15 ` Shah, Tanmay
0 siblings, 1 reply; 5+ messages in thread
From: Padhi, Beleswar @ 2026-04-25 3:51 UTC (permalink / raw)
To: Tanmay Shah, michal.simek, andersson, mathieu.poirier
Cc: linux-arm-kernel, linux-kernel, linux-remoteproc
Hi Tanmay,
In $subject-line, s/remote node/remoteproc
On 4/25/2026 8:32 AM, Tanmay Shah wrote:
> The remote state is set to RPROC_DETACHED if the resource table is found
> in the memory. However, this can be wrong if the remote is not started,
> but firmware is still loaded in the memory. Use PM_GET_NODE_STATUS call
> to the firmware to request the state of the RPU node. If the RPU is
> actually out of reset and running, only then move the remote state to
> RPROC_DETACHED, otherwise keep the remote state to RPROC_OFFLINE.
This is a good additional check. However, one thing to note is
remoteproc core
framework will load the firmware if the state is set to RPROC_OFFLINE. This
will override the existing firmware in the memory, I hope that is not
fatal for
your usecase?
>
> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
> ---
> drivers/firmware/xilinx/zynqmp.c | 28 +++++++++++++++++++
> drivers/remoteproc/xlnx_r5_remoteproc.c | 37 ++++++++++++++++++-------
> include/linux/firmware/xlnx-zynqmp.h | 21 ++++++++++++++
> 3 files changed, 76 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
> index fbe8510f4927..af838b2dc327 100644
> --- a/drivers/firmware/xilinx/zynqmp.c
> +++ b/drivers/firmware/xilinx/zynqmp.c
> @@ -1450,6 +1450,34 @@ int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
> }
> EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status);
>
> +/**
> + * zynqmp_pm_get_rpu_node_status - PM call to request a RPU node's current power state
> + * @node: ID of the RPU component or sub-system in question
> + * @status: Current operating state of the requested RPU node.
> + * @requirements: Current requirements asserted on the RPU node.
> + * @usage: Usage information, used for RPU slave nodes only:
> + * PM_USAGE_NO_MASTER - No master is currently using
> + * the node
> + * PM_USAGE_CURRENT_MASTER - Only requesting master is
> + * currently using the node
> + * PM_USAGE_OTHER_MASTER - Only other masters are
> + * currently using the node
> + * PM_USAGE_BOTH_MASTERS - Both the current and at least
> + * one other master is currently
> + * using the node
> + *
> + * Return: Returns status, either success or error+reason
> + */
> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
> + u32 *const requirements, u32 *const usage)
> +{
> + if (zynqmp_pm_feature(PM_GET_NODE_STATUS) < PM_API_VERSION_2)
> + return -EOPNOTSUPP;
> +
> + return zynqmp_pm_get_node_status(node, status, requirements, usage);
> +}
> +EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_node_status);
> +
> /**
> * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to
> * be powered down forcefully
> diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
> index 50a9974f3202..e2f25d94177d 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,32 @@ 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) {
> + if (zynqmp_r5_get_rsc_table_va(r5_core))
> + dev_dbg(r5_core->dev, "rsc tbl not found\n");
Do you still want to set state = RPROC_DETACHED if resource table is not
found in the
memory?
Thanks,
Beleswar
> + r5_core->rproc->state = RPROC_DETACHED;
> + }
> }
>
> return 0;
> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
> index d70dcd462b44..7e27b0f7bf7e 100644
> --- a/include/linux/firmware/xlnx-zynqmp.h
> +++ b/include/linux/firmware/xlnx-zynqmp.h
> @@ -542,6 +542,18 @@ enum pm_gem_config_type {
> GEM_CONFIG_FIXED = 2,
> };
>
> +/**
> + * enum pm_node_status - Device node status provided by xilpm fw
> + * @PM_NODE_UNUSED: Device is not used
> + * @PM_NODE_RUNNING: Device is power-on and out of reset
> + * @PM_NODE_HALT: Device is power-on but in the reset state
> + */
> +enum pm_node_status {
> + PM_NODE_UNUSED = 0,
> + PM_NODE_RUNNING = 1,
> + PM_NODE_HALT = 12,
> +};
> +
> /**
> * struct zynqmp_pm_query_data - PM query data
> * @qid: query ID
> @@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode);
> int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
> int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
> u32 *const requirements, u32 *const usage);
> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
> + u32 *const requirements, u32 *const usage);
> int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
> int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
> u32 value);
> @@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
> return -ENODEV;
> }
>
> +static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
> + u32 *const requirements,
> + u32 *const usage)
> +{
> + return -ENODEV;
> +}
> +
> static inline int zynqmp_pm_set_sd_config(u32 node,
> enum pm_sd_config_type config,
> u32 value)
>
> base-commit: 6f860d238b44da8ac57be25289b9f4410691c4e2
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] remoteproc: xlnx: check remote node state
2026-04-25 3:51 ` Padhi, Beleswar
@ 2026-04-27 16:15 ` Shah, Tanmay
2026-04-27 17:52 ` Mathieu Poirier
0 siblings, 1 reply; 5+ messages in thread
From: Shah, Tanmay @ 2026-04-27 16:15 UTC (permalink / raw)
To: Padhi, Beleswar, Tanmay Shah, michal.simek, andersson,
mathieu.poirier
Cc: linux-arm-kernel, linux-kernel, linux-remoteproc
Hello Beleswar,
Thanks for reviews. Please find my answer below:
On 4/24/2026 10:51 PM, Padhi, Beleswar wrote:
> Hi Tanmay,
>
> In $subject-line, s/remote node/remoteproc
>
Ack. 'node' is platform management firmware term, which might not be
right here. subject line already contains remoteproc so no need to have
it again. Instead, will replace 'node' with 'core'. new subject:
remoteproc: xlnx: check remote core state.
> On 4/25/2026 8:32 AM, Tanmay Shah wrote:
>> The remote state is set to RPROC_DETACHED if the resource table is found
>> in the memory. However, this can be wrong if the remote is not started,
>> but firmware is still loaded in the memory. Use PM_GET_NODE_STATUS call
>> to the firmware to request the state of the RPU node. If the RPU is
>> actually out of reset and running, only then move the remote state to
>> RPROC_DETACHED, otherwise keep the remote state to RPROC_OFFLINE.
>
>
> This is a good additional check. However, one thing to note is
> remoteproc core
> framework will load the firmware if the state is set to RPROC_OFFLINE. This
> will override the existing firmware in the memory, I hope that is not
> fatal for
> your usecase?
>
That is expected. If remote core is 'offline' during driver probe then
any firmware already in the memory becomes irrelevant and new firmware
can be loaded.
>>
>> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
>> ---
>> drivers/firmware/xilinx/zynqmp.c | 28 +++++++++++++++++++
>> drivers/remoteproc/xlnx_r5_remoteproc.c | 37 ++++++++++++++++++-------
>> include/linux/firmware/xlnx-zynqmp.h | 21 ++++++++++++++
>> 3 files changed, 76 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/
>> xilinx/zynqmp.c
>> index fbe8510f4927..af838b2dc327 100644
>> --- a/drivers/firmware/xilinx/zynqmp.c
>> +++ b/drivers/firmware/xilinx/zynqmp.c
>> @@ -1450,6 +1450,34 @@ int zynqmp_pm_get_node_status(const u32 node,
>> u32 *const status,
>> }
>> EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status);
>> +/**
>> + * zynqmp_pm_get_rpu_node_status - PM call to request a RPU node's
>> current power state
>> + * @node: ID of the RPU component or sub-system in question
>> + * @status: Current operating state of the requested RPU node.
>> + * @requirements: Current requirements asserted on the RPU node.
>> + * @usage: Usage information, used for RPU slave nodes only:
>> + * PM_USAGE_NO_MASTER - No master is currently using
>> + * the node
>> + * PM_USAGE_CURRENT_MASTER - Only requesting master is
>> + * currently using the node
>> + * PM_USAGE_OTHER_MASTER - Only other masters are
>> + * currently using the node
>> + * PM_USAGE_BOTH_MASTERS - Both the current and at least
>> + * one other master is currently
>> + * using the node
>> + *
>> + * Return: Returns status, either success or error+reason
>> + */
>> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
>> + u32 *const requirements, u32 *const usage)
>> +{
>> + if (zynqmp_pm_feature(PM_GET_NODE_STATUS) < PM_API_VERSION_2)
>> + return -EOPNOTSUPP;
>> +
>> + return zynqmp_pm_get_node_status(node, status, requirements, usage);
>> +}
>> +EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_node_status);
>> +
>> /**
>> * zynqmp_pm_force_pwrdwn - PM call to request for another PU or
>> subsystem to
>> * be powered down forcefully
>> diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/
>> remoteproc/xlnx_r5_remoteproc.c
>> index 50a9974f3202..e2f25d94177d 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,32 @@ 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) {
>> + if (zynqmp_r5_get_rsc_table_va(r5_core))
>> + dev_dbg(r5_core->dev, "rsc tbl not found\n");
>
>
> Do you still want to set state = RPROC_DETACHED if resource table is not
> found in the
> memory?
>
Yes. Not all the firmware that is running on 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.
Thanks.
> Thanks,
> Beleswar
>
>> + r5_core->rproc->state = RPROC_DETACHED;
>> + }
>> }
>> return 0;
>> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/
>> firmware/xlnx-zynqmp.h
>> index d70dcd462b44..7e27b0f7bf7e 100644
>> --- a/include/linux/firmware/xlnx-zynqmp.h
>> +++ b/include/linux/firmware/xlnx-zynqmp.h
>> @@ -542,6 +542,18 @@ enum pm_gem_config_type {
>> GEM_CONFIG_FIXED = 2,
>> };
>> +/**
>> + * enum pm_node_status - Device node status provided by xilpm fw
>> + * @PM_NODE_UNUSED: Device is not used
>> + * @PM_NODE_RUNNING: Device is power-on and out of reset
>> + * @PM_NODE_HALT: Device is power-on but in the reset state
>> + */
>> +enum pm_node_status {
>> + PM_NODE_UNUSED = 0,
>> + PM_NODE_RUNNING = 1,
>> + PM_NODE_HALT = 12,
>> +};
>> +
>> /**
>> * struct zynqmp_pm_query_data - PM query data
>> * @qid: query ID
>> @@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum
>> rpu_oper_mode rpu_mode);
>> int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
>> int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
>> u32 *const requirements, u32 *const usage);
>> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
>> + u32 *const requirements, u32 *const usage);
>> int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config,
>> u32 value);
>> int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
>> u32 value);
>> @@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const
>> u32 node, u32 *const status,
>> return -ENODEV;
>> }
>> +static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32
>> *const status,
>> + u32 *const requirements,
>> + u32 *const usage)
>> +{
>> + return -ENODEV;
>> +}
>> +
>> static inline int zynqmp_pm_set_sd_config(u32 node,
>> enum pm_sd_config_type config,
>> u32 value)
>>
>> base-commit: 6f860d238b44da8ac57be25289b9f4410691c4e2
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] remoteproc: xlnx: check remote node state
2026-04-27 16:15 ` Shah, Tanmay
@ 2026-04-27 17:52 ` Mathieu Poirier
2026-04-27 18:51 ` Shah, Tanmay
0 siblings, 1 reply; 5+ messages in thread
From: Mathieu Poirier @ 2026-04-27 17:52 UTC (permalink / raw)
To: tanmay.shah
Cc: Padhi, Beleswar, michal.simek, andersson, linux-arm-kernel,
linux-kernel, linux-remoteproc
Good morning
On Mon, Apr 27, 2026 at 11:15:29AM -0500, Shah, Tanmay wrote:
> Hello Beleswar,
>
> Thanks for reviews. Please find my answer below:
>
> On 4/24/2026 10:51 PM, Padhi, Beleswar wrote:
> > Hi Tanmay,
> >
> > In $subject-line, s/remote node/remoteproc
> >
>
> Ack. 'node' is platform management firmware term, which might not be
> right here. subject line already contains remoteproc so no need to have
> it again. Instead, will replace 'node' with 'core'. new subject:
>
> remoteproc: xlnx: check remote core state.
>
Much better.
> > On 4/25/2026 8:32 AM, Tanmay Shah wrote:
> >> The remote state is set to RPROC_DETACHED if the resource table is found
> >> in the memory. However, this can be wrong if the remote is not started,
> >> but firmware is still loaded in the memory. Use PM_GET_NODE_STATUS call
> >> to the firmware to request the state of the RPU node. If the RPU is
> >> actually out of reset and running, only then move the remote state to
> >> RPROC_DETACHED, otherwise keep the remote state to RPROC_OFFLINE.
> >
> >
> > This is a good additional check. However, one thing to note is
> > remoteproc core
> > framework will load the firmware if the state is set to RPROC_OFFLINE. This
> > will override the existing firmware in the memory, I hope that is not
> > fatal for
> > your usecase?
> >
>
> That is expected. If remote core is 'offline' during driver probe then
> any firmware already in the memory becomes irrelevant and new firmware
> can be loaded.
>
> >>
> >> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
> >> ---
> >> drivers/firmware/xilinx/zynqmp.c | 28 +++++++++++++++++++
> >> drivers/remoteproc/xlnx_r5_remoteproc.c | 37 ++++++++++++++++++-------
> >> include/linux/firmware/xlnx-zynqmp.h | 21 ++++++++++++++
> >> 3 files changed, 76 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/
> >> xilinx/zynqmp.c
> >> index fbe8510f4927..af838b2dc327 100644
> >> --- a/drivers/firmware/xilinx/zynqmp.c
> >> +++ b/drivers/firmware/xilinx/zynqmp.c
> >> @@ -1450,6 +1450,34 @@ int zynqmp_pm_get_node_status(const u32 node,
> >> u32 *const status,
> >> }
> >> EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status);
> >> +/**
> >> + * zynqmp_pm_get_rpu_node_status - PM call to request a RPU node's
> >> current power state
> >> + * @node: ID of the RPU component or sub-system in question
> >> + * @status: Current operating state of the requested RPU node.
> >> + * @requirements: Current requirements asserted on the RPU node.
> >> + * @usage: Usage information, used for RPU slave nodes only:
> >> + * PM_USAGE_NO_MASTER - No master is currently using
> >> + * the node
> >> + * PM_USAGE_CURRENT_MASTER - Only requesting master is
> >> + * currently using the node
> >> + * PM_USAGE_OTHER_MASTER - Only other masters are
> >> + * currently using the node
> >> + * PM_USAGE_BOTH_MASTERS - Both the current and at least
> >> + * one other master is currently
> >> + * using the node
> >> + *
> >> + * Return: Returns status, either success or error+reason
> >> + */
> >> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
> >> + u32 *const requirements, u32 *const usage)
> >> +{
> >> + if (zynqmp_pm_feature(PM_GET_NODE_STATUS) < PM_API_VERSION_2)
> >> + return -EOPNOTSUPP;
> >> +
> >> + return zynqmp_pm_get_node_status(node, status, requirements, usage);
> >> +}
> >> +EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_node_status);
> >> +
> >> /**
> >> * zynqmp_pm_force_pwrdwn - PM call to request for another PU or
> >> subsystem to
> >> * be powered down forcefully
> >> diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/
> >> remoteproc/xlnx_r5_remoteproc.c
> >> index 50a9974f3202..e2f25d94177d 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,32 @@ 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) {
> >> + if (zynqmp_r5_get_rsc_table_va(r5_core))
> >> + dev_dbg(r5_core->dev, "rsc tbl not found\n");
> >
> >
> > Do you still want to set state = RPROC_DETACHED if resource table is not
> > found in the
> > memory?
> >
>
> Yes. Not all the firmware that is running on 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.
Please add the above explanation to the inlined comment. Otherwise I'm good
with this patch but I'll need an RB from Michael before moving forward.
Do you see this as a bug fix? Is there a point adding this patch to the stable
kernels?
>
> Thanks.
>
> > Thanks,
> > Beleswar
> >
> >> + r5_core->rproc->state = RPROC_DETACHED;
> >> + }
> >> }
> >> return 0;
> >> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/
> >> firmware/xlnx-zynqmp.h
> >> index d70dcd462b44..7e27b0f7bf7e 100644
> >> --- a/include/linux/firmware/xlnx-zynqmp.h
> >> +++ b/include/linux/firmware/xlnx-zynqmp.h
> >> @@ -542,6 +542,18 @@ enum pm_gem_config_type {
> >> GEM_CONFIG_FIXED = 2,
> >> };
> >> +/**
> >> + * enum pm_node_status - Device node status provided by xilpm fw
> >> + * @PM_NODE_UNUSED: Device is not used
> >> + * @PM_NODE_RUNNING: Device is power-on and out of reset
> >> + * @PM_NODE_HALT: Device is power-on but in the reset state
> >> + */
> >> +enum pm_node_status {
> >> + PM_NODE_UNUSED = 0,
> >> + PM_NODE_RUNNING = 1,
> >> + PM_NODE_HALT = 12,
> >> +};
> >> +
> >> /**
> >> * struct zynqmp_pm_query_data - PM query data
> >> * @qid: query ID
> >> @@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum
> >> rpu_oper_mode rpu_mode);
> >> int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
> >> int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
> >> u32 *const requirements, u32 *const usage);
> >> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
> >> + u32 *const requirements, u32 *const usage);
> >> int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config,
> >> u32 value);
> >> int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
> >> u32 value);
> >> @@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const
> >> u32 node, u32 *const status,
> >> return -ENODEV;
> >> }
> >> +static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32
> >> *const status,
> >> + u32 *const requirements,
> >> + u32 *const usage)
> >> +{
> >> + return -ENODEV;
> >> +}
> >> +
> >> static inline int zynqmp_pm_set_sd_config(u32 node,
> >> enum pm_sd_config_type config,
> >> u32 value)
> >>
> >> base-commit: 6f860d238b44da8ac57be25289b9f4410691c4e2
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] remoteproc: xlnx: check remote node state
2026-04-27 17:52 ` Mathieu Poirier
@ 2026-04-27 18:51 ` Shah, Tanmay
0 siblings, 0 replies; 5+ messages in thread
From: Shah, Tanmay @ 2026-04-27 18:51 UTC (permalink / raw)
To: Mathieu Poirier, tanmay.shah
Cc: Padhi, Beleswar, michal.simek, andersson, linux-arm-kernel,
linux-kernel, linux-remoteproc
On 4/27/2026 12:52 PM, Mathieu Poirier wrote:
> Good morning
>
> On Mon, Apr 27, 2026 at 11:15:29AM -0500, Shah, Tanmay wrote:
>> Hello Beleswar,
>>
>> Thanks for reviews. Please find my answer below:
>>
>> On 4/24/2026 10:51 PM, Padhi, Beleswar wrote:
>>> Hi Tanmay,
>>>
>>> In $subject-line, s/remote node/remoteproc
>>>
>>
>> Ack. 'node' is platform management firmware term, which might not be
>> right here. subject line already contains remoteproc so no need to have
>> it again. Instead, will replace 'node' with 'core'. new subject:
>>
>> remoteproc: xlnx: check remote core state.
>>
>
> Much better.
>
>>> On 4/25/2026 8:32 AM, Tanmay Shah wrote:
>>>> The remote state is set to RPROC_DETACHED if the resource table is found
>>>> in the memory. However, this can be wrong if the remote is not started,
>>>> but firmware is still loaded in the memory. Use PM_GET_NODE_STATUS call
>>>> to the firmware to request the state of the RPU node. If the RPU is
>>>> actually out of reset and running, only then move the remote state to
>>>> RPROC_DETACHED, otherwise keep the remote state to RPROC_OFFLINE.
>>>
>>>
>>> This is a good additional check. However, one thing to note is
[...]
>>>> +
>>>> + /*
>>>> + * 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) {
>>>> + if (zynqmp_r5_get_rsc_table_va(r5_core))
>>>> + dev_dbg(r5_core->dev, "rsc tbl not found\n");
>>>
>>>
>>> Do you still want to set state = RPROC_DETACHED if resource table is not
>>> found in the
>>> memory?
>>>
>>
>> Yes. Not all the firmware that is running on 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.
>
> Please add the above explanation to the inlined comment. Otherwise I'm good
> with this patch but I'll need an RB from Michael before moving forward.
>
Ack.
> Do you see this as a bug fix? Is there a point adding this patch to the stable
> kernels?
>
That's a good point. I should add Fixes tag as well, for the commit that
introduced attach-detach feature.
I will do that in v2.
Thanks,
Tanmay
>>
>> Thanks.
>>
>>> Thanks,
>>> Beleswar
>>>
>>>> + r5_core->rproc->state = RPROC_DETACHED;
>>>> + }
>>>> }
>>>> return 0;
>>>> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/
>>>> firmware/xlnx-zynqmp.h
>>>> index d70dcd462b44..7e27b0f7bf7e 100644
>>>> --- a/include/linux/firmware/xlnx-zynqmp.h
>>>> +++ b/include/linux/firmware/xlnx-zynqmp.h
>>>> @@ -542,6 +542,18 @@ enum pm_gem_config_type {
>>>> GEM_CONFIG_FIXED = 2,
>>>> };
>>>> +/**
>>>> + * enum pm_node_status - Device node status provided by xilpm fw
>>>> + * @PM_NODE_UNUSED: Device is not used
>>>> + * @PM_NODE_RUNNING: Device is power-on and out of reset
>>>> + * @PM_NODE_HALT: Device is power-on but in the reset state
>>>> + */
>>>> +enum pm_node_status {
>>>> + PM_NODE_UNUSED = 0,
>>>> + PM_NODE_RUNNING = 1,
>>>> + PM_NODE_HALT = 12,
>>>> +};
>>>> +
>>>> /**
>>>> * struct zynqmp_pm_query_data - PM query data
>>>> * @qid: query ID
>>>> @@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum
>>>> rpu_oper_mode rpu_mode);
>>>> int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
>>>> int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
>>>> u32 *const requirements, u32 *const usage);
>>>> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
>>>> + u32 *const requirements, u32 *const usage);
>>>> int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config,
>>>> u32 value);
>>>> int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
>>>> u32 value);
>>>> @@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const
>>>> u32 node, u32 *const status,
>>>> return -ENODEV;
>>>> }
>>>> +static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32
>>>> *const status,
>>>> + u32 *const requirements,
>>>> + u32 *const usage)
>>>> +{
>>>> + return -ENODEV;
>>>> +}
>>>> +
>>>> static inline int zynqmp_pm_set_sd_config(u32 node,
>>>> enum pm_sd_config_type config,
>>>> u32 value)
>>>>
>>>> base-commit: 6f860d238b44da8ac57be25289b9f4410691c4e2
>>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-27 18:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-25 3:02 [PATCH] remoteproc: xlnx: check remote node state Tanmay Shah
2026-04-25 3:51 ` Padhi, Beleswar
2026-04-27 16:15 ` Shah, Tanmay
2026-04-27 17:52 ` Mathieu Poirier
2026-04-27 18:51 ` Shah, Tanmay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox