This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5a3621a5f8c217a1cd9f66c05f7bb7ade4fe8fa0
Author: wangshaoxin <[email protected]>
AuthorDate: Wed Mar 19 16:36:10 2025 +0800

    drivers/rpmsg: add rpmsg_foreach() to walk the rpmsg devices
    
    rpmsg_ioctl() open-coded the walk over g_rpmsg under g_rpmsg_lock.
    Factor it out into rpmsg_foreach(), declared in the private
    drivers/rpmsg/rpmsg.h, so other users inside drivers/rpmsg (such as a
    procfs entry) can walk the devices the same way.  rpmsg_ioctl() is now
    a callback on top of it.  The lock is skipped in interrupt context and
    in the idle task, as in rpmsg_modify_signals().
    
    Signed-off-by: wangshaoxin <[email protected]>
    Signed-off-by: Bowen Wang <[email protected]>
---
 drivers/rpmsg/rpmsg.c | 64 ++++++++++++++++++++++++++++++++++++---------------
 drivers/rpmsg/rpmsg.h |  9 ++++++++
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/drivers/rpmsg/rpmsg.c b/drivers/rpmsg/rpmsg.c
index 822b72465dc..7723dc98876 100644
--- a/drivers/rpmsg/rpmsg.c
+++ b/drivers/rpmsg/rpmsg.c
@@ -58,6 +58,13 @@ struct rpmsg_cb_s
   struct metal_list node;
 };
 
+struct rpmsg_ioctl_s
+{
+  FAR const char *cpuname;
+  int             cmd;
+  unsigned long   arg;
+};
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -555,12 +562,46 @@ void rpmsg_unregister(FAR const char *path, FAR struct 
rpmsg_s *rpmsg)
   metal_finish();
 }
 
+static int rpmsg_ioctl_foreach_cb(FAR struct rpmsg_s *rpmsg, FAR void *arg)
+{
+  FAR struct rpmsg_ioctl_s *info = (FAR struct rpmsg_ioctl_s *)arg;
+
+  if (!info->cpuname || !strcmp(rpmsg->cpuname, info->cpuname))
+    {
+      return rpmsg_dev_ioctl_(rpmsg, info->cmd, info->arg);
+    }
+
+  return 0;
+}
+
 int rpmsg_ioctl(FAR const char *cpuname, int cmd, unsigned long arg)
+{
+  struct rpmsg_ioctl_s info;
+
+  info.cpuname = cpuname;
+  info.cmd     = cmd;
+  info.arg     = arg;
+
+  return rpmsg_foreach(rpmsg_ioctl_foreach_cb, &info);
+}
+
+int rpmsg_panic(FAR const char *cpuname)
+{
+  return rpmsg_ioctl(cpuname, RPMSGIOC_PANIC, 0);
+}
+
+void rpmsg_dump_all(void)
+{
+  rpmsg_ioctl(NULL, RPMSGIOC_DUMP, 0);
+}
+
+int rpmsg_foreach(rpmsg_foreach_t handler, FAR void *args)
 {
   FAR struct metal_list *node;
+  bool needlock = !up_interrupt_context() && !sched_idletask();
   int ret = OK;
 
-  if (!up_interrupt_context())
+  if (needlock)
     {
       down_read(&g_rpmsg_lock);
     }
@@ -570,17 +611,14 @@ int rpmsg_ioctl(FAR const char *cpuname, int cmd, 
unsigned long arg)
       FAR struct rpmsg_s *rpmsg =
         metal_container_of(node, struct rpmsg_s, node);
 
-      if (!cpuname || !strcmp(rpmsg->cpuname, cpuname))
+      ret = handler(rpmsg, args);
+      if (ret < 0)
         {
-          ret = rpmsg_dev_ioctl_(rpmsg, cmd, arg);
-          if (ret < 0)
-            {
-              break;
-            }
+          break;
         }
     }
 
-  if (!up_interrupt_context())
+  if (needlock)
     {
       up_read(&g_rpmsg_lock);
     }
@@ -588,16 +626,6 @@ int rpmsg_ioctl(FAR const char *cpuname, int cmd, unsigned 
long arg)
   return ret;
 }
 
-int rpmsg_panic(FAR const char *cpuname)
-{
-  return rpmsg_ioctl(cpuname, RPMSGIOC_PANIC, 0);
-}
-
-void rpmsg_dump_all(void)
-{
-  rpmsg_ioctl(NULL, RPMSGIOC_DUMP, 0);
-}
-
 void rpmsg_modify_signals(FAR struct rpmsg_s *rpmsg,
                           int setflags, int clrflags)
 {
diff --git a/drivers/rpmsg/rpmsg.h b/drivers/rpmsg/rpmsg.h
index f2dd48f4346..0b79377f8b8 100644
--- a/drivers/rpmsg/rpmsg.h
+++ b/drivers/rpmsg/rpmsg.h
@@ -29,6 +29,13 @@
 
 #include <nuttx/rpmsg/rpmsg.h>
 
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+CODE typedef int (*rpmsg_foreach_t)(FAR struct rpmsg_s *rpmsg,
+                                    FAR void *args);
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -59,5 +66,7 @@ int rpmsg_register(FAR const char *path, FAR struct rpmsg_s 
*rpmsg,
                    FAR const struct rpmsg_ops_s *ops);
 void rpmsg_unregister(FAR const char *path, FAR struct rpmsg_s *rpmsg);
 
+int rpmsg_foreach(rpmsg_foreach_t handler, FAR void *args);
+
 #endif /* CONFIG_RPMSG */
 #endif /* __DRIVERS_RPMSG_RPMSG_H */

Reply via email to