acassis commented on code in PR #16798:
URL: https://github.com/apache/nuttx/pull/16798#discussion_r2242616970


##########
arch/arm64/src/imx9/imx9_scmi.h:
##########
@@ -0,0 +1,157 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_scmi.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_IMX9_IMX9_SCMI_H
+#define __ARCH_ARM_SRC_IMX9_IMX9_SCMI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SM_PLATFORM_A2P      0 /* SCMI Agent -> SCMI Platform */
+#define SM_PLATFORM_NOTIFY   1 /* SCMI Platform -> SCMI Agent */
+#define SM_PLATFORM_PRIORITY 2
+
+#define SM_CLOCK_RATE_MASK 0xFFFFFFFFU
+
+/* SCMI clock round options */
+#define SCMI_CLOCK_ROUND_DOWN  0U /* Round down */
+#define SCMI_CLOCK_ROUND_UP    1U /* Round up */
+#define SCMI_CLOCK_ROUND_AUTO  2U /* Round to nearest */
+
+/* SCMI clock rate flags */
+
+#define SCMI_CLOCK_RATE_FLAGS_ROUND(x)    (((x) & 0x3U) << 2U) /* Round 
up/down */
+#define SCMI_CLOCK_RATE_FLAGS_NO_RESP(x)  (((x) & 0x1U) << 1U) /* Ignore 
delayed response */
+#define SCMI_CLOCK_RATE_FLAGS_ASYNC(x)    (((x) & 0x1U) << 0U) /* Async flag */
+
+/* SCMI clock config attributes */
+
+#define SCMI_CLOCK_CONFIG_SET_OEM(x)     (((x) & 0xFFU) << 16U) /* OEM 
specified config type */
+#define SCMI_CLOCK_CONFIG_SET_ENABLE(x)  (((x) & 0x3U) << 0U)   /* 
Enable/Disable */
+
+/* SCMI pin control types */
+
+#define SCMI_PINCTRL_SEL_PIN         0U
+#define SCMI_PINCTRL_SEL_GROUP       1U
+#define SCMI_PINCTRL_TYPE_MUX        192U /* Mux type */
+#define SCMI_PINCTRL_TYPE_CONFIG     193U /* Config type */
+#define SCMI_PINCTRL_TYPE_DAISY_ID   194U /* Daisy ID type */
+#define SCMI_PINCTRL_TYPE_DAISY_CFG  195U /* Daisy config type */
+#define SCMI_PINCTRL_SET_ATTR_NUM_CONFIGS(x)  (((x) & 0xFFU) << 2U)
+#define SCMI_PINCTRL_SET_ATTR_SELECTOR(x)     (((x) & 0x3U) << 0U)
+
+/* Pinctrl */
+#define SM_PLATFORM_PINCTRL_MUX_MODE_MASK  (0x7U)
+#define SM_PLATFORM_PINCTRL_MUX_MODE_SHIFT (0U)
+#define SM_PLATFORM_PINCTRL_MUX_MODE(x) \
+    (((uint32_t)(((uint32_t)(x)) << SM_PLATFORM_PINCTRL_MUX_MODE_SHIFT)) & 
SM_PLATFORM_PINCTRL_MUX_MODE_MASK)
+
+#define SM_PLATFORM_PINCTRL_SION_MASK  (0x10)
+#define SM_PLATFORM_PINCTRL_SION_SHIFT (4U)
+#define SM_PLATFORM_PINCTRL_SION(x) \
+    (((uint32_t)(((uint32_t)(x)) << SM_PLATFORM_PINCTRL_SION_SHIFT)) & 
SM_PLATFORM_PINCTRL_SION_MASK)
+
+#define SM_PLATFORM_PINCTRL_BASE         IMX9_IOMUXC_BASE
+#define SM_PLATFORM_PINCTRL_MUXREG_OFF   (SM_PLATFORM_PINCTRL_BASE)
+#define SM_PLATFORM_PINCTRL_CFGREG_OFF   (SM_PLATFORM_PINCTRL_BASE + 0x204) /* 
0x443c0204 */
+#define SM_PLATFORM_PINCTRL_DAISYREG_OFF (SM_PLATFORM_PINCTRL_BASE + 0x408) /* 
0x443c0408 */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+typedef struct
+{
+    uint32_t channel;    /* channel id: SCMI_A2P, SCMI_NOTIRY, SCMI_P2A, */
+    uint32_t rateu;
+    uint32_t ratel;
+    uint32_t clk_id;     /* clock device id */
+    uint32_t pclk_id;    /* parent clock device id */
+    uint32_t div;        /* clock divider */
+    uint32_t attributes; /* clock attributes */
+    uint32_t oem_config_val;
+    uint32_t flags;
+} sm_clock_t;
+
+typedef struct
+{
+    uint32_t channel;
+    uint32_t mux_register;
+    uint32_t mux_mode;
+    uint32_t input_register;
+    uint32_t input_daisy;
+    uint32_t config_register;
+    uint32_t config_value;
+    uint32_t input_on_field;
+} sm_pinctrl_t;
+
+/* SCMI clock rate */
+
+typedef struct
+{
+    uint32_t lower; /* Lower 32 bits of the physical rate in Hz */
+    uint32_t upper; /* Upper 32 bits of the physical rate in Hz */
+} scmi_clock_rate_t;
+
+/* SCMI pin control config */
+
+typedef struct
+{
+    uint32_t type;  /* The type of config */
+    uint32_t value; /* The configuration value */
+} scmi_pin_config_t;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imx9_scmi_initialize
+ *
+ * Description:

Review Comment:
   Please include Description



##########
arch/arm64/src/imx9/imx9_scmi.h:
##########
@@ -0,0 +1,157 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_scmi.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_IMX9_IMX9_SCMI_H
+#define __ARCH_ARM_SRC_IMX9_IMX9_SCMI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SM_PLATFORM_A2P      0 /* SCMI Agent -> SCMI Platform */
+#define SM_PLATFORM_NOTIFY   1 /* SCMI Platform -> SCMI Agent */
+#define SM_PLATFORM_PRIORITY 2
+
+#define SM_CLOCK_RATE_MASK 0xFFFFFFFFU
+
+/* SCMI clock round options */
+#define SCMI_CLOCK_ROUND_DOWN  0U /* Round down */
+#define SCMI_CLOCK_ROUND_UP    1U /* Round up */
+#define SCMI_CLOCK_ROUND_AUTO  2U /* Round to nearest */
+
+/* SCMI clock rate flags */
+
+#define SCMI_CLOCK_RATE_FLAGS_ROUND(x)    (((x) & 0x3U) << 2U) /* Round 
up/down */
+#define SCMI_CLOCK_RATE_FLAGS_NO_RESP(x)  (((x) & 0x1U) << 1U) /* Ignore 
delayed response */
+#define SCMI_CLOCK_RATE_FLAGS_ASYNC(x)    (((x) & 0x1U) << 0U) /* Async flag */
+
+/* SCMI clock config attributes */
+
+#define SCMI_CLOCK_CONFIG_SET_OEM(x)     (((x) & 0xFFU) << 16U) /* OEM 
specified config type */
+#define SCMI_CLOCK_CONFIG_SET_ENABLE(x)  (((x) & 0x3U) << 0U)   /* 
Enable/Disable */
+
+/* SCMI pin control types */
+
+#define SCMI_PINCTRL_SEL_PIN         0U
+#define SCMI_PINCTRL_SEL_GROUP       1U
+#define SCMI_PINCTRL_TYPE_MUX        192U /* Mux type */
+#define SCMI_PINCTRL_TYPE_CONFIG     193U /* Config type */
+#define SCMI_PINCTRL_TYPE_DAISY_ID   194U /* Daisy ID type */
+#define SCMI_PINCTRL_TYPE_DAISY_CFG  195U /* Daisy config type */
+#define SCMI_PINCTRL_SET_ATTR_NUM_CONFIGS(x)  (((x) & 0xFFU) << 2U)
+#define SCMI_PINCTRL_SET_ATTR_SELECTOR(x)     (((x) & 0x3U) << 0U)
+
+/* Pinctrl */
+#define SM_PLATFORM_PINCTRL_MUX_MODE_MASK  (0x7U)
+#define SM_PLATFORM_PINCTRL_MUX_MODE_SHIFT (0U)
+#define SM_PLATFORM_PINCTRL_MUX_MODE(x) \
+    (((uint32_t)(((uint32_t)(x)) << SM_PLATFORM_PINCTRL_MUX_MODE_SHIFT)) & 
SM_PLATFORM_PINCTRL_MUX_MODE_MASK)
+
+#define SM_PLATFORM_PINCTRL_SION_MASK  (0x10)
+#define SM_PLATFORM_PINCTRL_SION_SHIFT (4U)
+#define SM_PLATFORM_PINCTRL_SION(x) \
+    (((uint32_t)(((uint32_t)(x)) << SM_PLATFORM_PINCTRL_SION_SHIFT)) & 
SM_PLATFORM_PINCTRL_SION_MASK)
+
+#define SM_PLATFORM_PINCTRL_BASE         IMX9_IOMUXC_BASE
+#define SM_PLATFORM_PINCTRL_MUXREG_OFF   (SM_PLATFORM_PINCTRL_BASE)
+#define SM_PLATFORM_PINCTRL_CFGREG_OFF   (SM_PLATFORM_PINCTRL_BASE + 0x204) /* 
0x443c0204 */
+#define SM_PLATFORM_PINCTRL_DAISYREG_OFF (SM_PLATFORM_PINCTRL_BASE + 0x408) /* 
0x443c0408 */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+typedef struct
+{
+    uint32_t channel;    /* channel id: SCMI_A2P, SCMI_NOTIRY, SCMI_P2A, */
+    uint32_t rateu;
+    uint32_t ratel;
+    uint32_t clk_id;     /* clock device id */
+    uint32_t pclk_id;    /* parent clock device id */
+    uint32_t div;        /* clock divider */
+    uint32_t attributes; /* clock attributes */
+    uint32_t oem_config_val;
+    uint32_t flags;
+} sm_clock_t;
+
+typedef struct
+{
+    uint32_t channel;
+    uint32_t mux_register;
+    uint32_t mux_mode;
+    uint32_t input_register;
+    uint32_t input_daisy;
+    uint32_t config_register;
+    uint32_t config_value;
+    uint32_t input_on_field;
+} sm_pinctrl_t;
+
+/* SCMI clock rate */
+
+typedef struct
+{
+    uint32_t lower; /* Lower 32 bits of the physical rate in Hz */
+    uint32_t upper; /* Upper 32 bits of the physical rate in Hz */
+} scmi_clock_rate_t;
+
+/* SCMI pin control config */
+
+typedef struct
+{
+    uint32_t type;  /* The type of config */
+    uint32_t value; /* The configuration value */
+} scmi_pin_config_t;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imx9_scmi_initialize
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void imx9_scmi_initialize(void);
+
+int32_t imx9_scmi_clockparentget(uint32_t channel, uint32_t clockid,
+    uint32_t *parentid);
+int32_t imx9_scmi_clockparentset(uint32_t channel, uint32_t clockid,
+    uint32_t parentid);
+int32_t imx9_scmi_clockrateget(uint32_t channel, uint32_t clockid,
+    scmi_clock_rate_t *rate);
+int32_t imx9_scmi_clockrateset(uint32_t channel, uint32_t clockid,
+    uint32_t flags, scmi_clock_rate_t rate);
+int32_t imx9_scmi_clockconfigset(uint32_t channel, uint32_t clockid,
+    uint32_t attributes, uint32_t oem_config_val);
+int32_t imx9_scmi_pinctrlconfigset(uint32_t channel, uint32_t identifier,
+    uint32_t attributes, const scmi_pin_config_t *configs);

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)
+{
+  up_disable_irq(priv->irq);
+}
+
+int imx95_mu_send_msg_non_blocking(struct imx9_mudev_s *priv,
+                                   uint32_t reg_index, uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg nonblocking idx=%d, msg=%d\n", reg_index, msg);
+
+  if ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -EBUSY;
+    }
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+  return OK;
+}
+
+void imx95_mu_send_msg(struct imx9_mudev_s *priv, uint32_t reg_index,
+                       uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg idx=%d, msg=%d\n", reg_index, msg);
+
+  /* Wait TX register to be empty. */
+
+  while ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    ;
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+}
+
+int imx95_mu_has_received_msg(struct imx9_mudev_s *priv, uint32_t reg_index)
+{
+  if ((getreg32(IMX9_MU_RSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -ENODATA;
+    }
+
+  return 0;
+}
+
+uint32_t imx95_mu_receive_msg_non_blocking(struct imx9_mudev_s *priv,
+                                           uint32_t reg_index)
+{
+  assert(reg_index < IMX9_MU_RR_REGARRAY_SIZE);
+
+  return getreg32(IMX9_MU_RR1(priv->mubase) +
+            (reg_index * sizeof(uint32_t)));
+}
+
+uint32_t imx95_mu_receive_msg(struct imx9_mudev_s *priv, uint32_t reg_index)

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)
+{
+  up_disable_irq(priv->irq);
+}
+
+int imx95_mu_send_msg_non_blocking(struct imx9_mudev_s *priv,
+                                   uint32_t reg_index, uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg nonblocking idx=%d, msg=%d\n", reg_index, msg);
+
+  if ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -EBUSY;
+    }
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+  return OK;
+}
+
+void imx95_mu_send_msg(struct imx9_mudev_s *priv, uint32_t reg_index,

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)
+{
+  up_disable_irq(priv->irq);
+}
+
+int imx95_mu_send_msg_non_blocking(struct imx9_mudev_s *priv,
+                                   uint32_t reg_index, uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg nonblocking idx=%d, msg=%d\n", reg_index, msg);
+
+  if ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -EBUSY;
+    }
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+  return OK;
+}
+
+void imx95_mu_send_msg(struct imx9_mudev_s *priv, uint32_t reg_index,
+                       uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg idx=%d, msg=%d\n", reg_index, msg);
+
+  /* Wait TX register to be empty. */
+
+  while ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    ;
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+}
+
+int imx95_mu_has_received_msg(struct imx9_mudev_s *priv, uint32_t reg_index)
+{
+  if ((getreg32(IMX9_MU_RSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -ENODATA;
+    }
+
+  return 0;
+}
+
+uint32_t imx95_mu_receive_msg_non_blocking(struct imx9_mudev_s *priv,

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)
+{
+  up_disable_irq(priv->irq);
+}
+
+int imx95_mu_send_msg_non_blocking(struct imx9_mudev_s *priv,

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)

Review Comment:
   Please include function Description comments.



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)
+{
+  up_disable_irq(priv->irq);
+}
+
+int imx95_mu_send_msg_non_blocking(struct imx9_mudev_s *priv,
+                                   uint32_t reg_index, uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg nonblocking idx=%d, msg=%d\n", reg_index, msg);
+
+  if ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -EBUSY;
+    }
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+  return OK;
+}
+
+void imx95_mu_send_msg(struct imx9_mudev_s *priv, uint32_t reg_index,
+                       uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg idx=%d, msg=%d\n", reg_index, msg);
+
+  /* Wait TX register to be empty. */
+
+  while ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    ;
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+}
+
+int imx95_mu_has_received_msg(struct imx9_mudev_s *priv, uint32_t reg_index)

Review Comment:
   Ditto



##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,253 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)
+{
+  up_disable_irq(priv->irq);
+}
+
+int imx95_mu_send_msg_non_blocking(struct imx9_mudev_s *priv,
+                                   uint32_t reg_index, uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg nonblocking idx=%d, msg=%d\n", reg_index, msg);
+
+  if ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -EBUSY;
+    }
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+  return OK;
+}
+
+void imx95_mu_send_msg(struct imx9_mudev_s *priv, uint32_t reg_index,
+                       uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg idx=%d, msg=%d\n", reg_index, msg);
+
+  /* Wait TX register to be empty. */
+
+  while ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    ;
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+}
+
+int imx95_mu_has_received_msg(struct imx9_mudev_s *priv, uint32_t reg_index)
+{
+  if ((getreg32(IMX9_MU_RSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -ENODATA;
+    }
+
+  return 0;
+}
+
+uint32_t imx95_mu_receive_msg_non_blocking(struct imx9_mudev_s *priv,
+                                           uint32_t reg_index)
+{
+  assert(reg_index < IMX9_MU_RR_REGARRAY_SIZE);
+
+  return getreg32(IMX9_MU_RR1(priv->mubase) +
+            (reg_index * sizeof(uint32_t)));
+}
+
+uint32_t imx95_mu_receive_msg(struct imx9_mudev_s *priv, uint32_t reg_index)
+{
+  assert(reg_index < IMX9_MU_RR_REGARRAY_SIZE);
+
+  /* Wait RX register to be full. */
+
+  while (imx95_mu_has_received_msg(priv, reg_index) == -ENODATA);
+
+  return getreg32(IMX9_MU_RR1(priv->mubase) +
+            (reg_index * sizeof(uint32_t)));
+}
+
+int imx95_mu_trigger_interrupts(struct imx9_mudev_s *priv,

Review Comment:
   Ditto



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to