linguini1 commented on code in PR #19005:
URL: https://github.com/apache/nuttx/pull/19005#discussion_r3334893749


##########
arch/arm64/src/am62x/am62x_gpio.c:
##########
@@ -0,0 +1,372 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_gpio.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_gpio.h"
+#include "hardware/am62x_memorymap.h"
+#include "am62x_gpio.h"
+#include "am62x_tisci.h"
+
+#ifdef CONFIG_AM62X_GPIO

Review Comment:
   Not needed if the file is already guarded in the build system. Ditto for 
everywhere else this is used.



##########
arch/arm64/src/am62x/am62x_i2c.c:
##########
@@ -0,0 +1,683 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_i2c.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+#include <nuttx/debug.h>
+#include <nuttx/irq.h>
+#include <nuttx/mutex.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/i2c/i2c_master.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_i2c.h"
+#include "hardware/am62x_memorymap.h"
+#include "am62x_i2c.h"
+#include "am62x_tisci.h"
+
+#if defined(CONFIG_AM62X_I2C0) || defined(CONFIG_AM62X_I2C1) || \
+    defined(CONFIG_AM62X_I2C2) || defined(CONFIG_AM62X_I2C3)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define AM62X_I2C_INPUT_CLOCK  96000000
+#define AM62X_I2C_INTERNAL_CLK 12000000
+
+#ifndef CONFIG_AM62X_I2CTIMEOSEC
+#  define CONFIG_AM62X_I2CTIMEOSEC 0
+#endif
+
+#ifndef CONFIG_AM62X_I2CTIMEOMS
+#  define CONFIG_AM62X_I2CTIMEOMS 500
+#endif
+
+#ifndef CONFIG_AM62X_I2CTIMEOTICKS
+#  define CONFIG_AM62X_I2CTIMEOTICKS \
+    (SEC2TICK(CONFIG_AM62X_I2CTIMEOSEC) + \
+     MSEC2TICK(CONFIG_AM62X_I2CTIMEOMS))
+#endif
+
+#define AM62X_I2C_INTERRUPTS   (I2C_IRQ_AL | I2C_IRQ_NACK | I2C_IRQ_ARDY | \
+                                I2C_IRQ_RRDY | I2C_IRQ_XRDY | \
+                                I2C_IRQ_AERR | I2C_IRQ_XUDF | I2C_IRQ_ROVR)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+enum am62x_i2c_state_e
+{
+  INTSTATE_IDLE = 0,
+  INTSTATE_WAITING,
+  INTSTATE_DONE,
+};
+
+struct am62x_i2c_config_s
+{
+  uintptr_t base;
+  int irq;
+  uint32_t devid;     /* TISCI device id (power/clock domain)              */
+  uint32_t clkid;     /* TISCI functional clock id                         */
+};
+
+struct am62x_i2c_priv_s
+{
+  const struct i2c_ops_s *ops;
+  const struct am62x_i2c_config_s *config;
+  int refs;
+  mutex_t lock;
+#ifndef CONFIG_I2C_POLLED
+  sem_t sem_isr;
+#endif
+  volatile uint8_t intstate;
+  struct i2c_msg_s *msgv;
+  int msgc;
+  int msgidx;
+  uint8_t *ptr;
+  int dcnt;
+  uint16_t flags;
+  uint32_t frequency;
+  uint32_t status;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int am62x_i2c_transfer(struct i2c_master_s *dev,
+                              struct i2c_msg_s *msgs, int count);
+#ifdef CONFIG_I2C_RESET
+static int am62x_i2c_reset(struct i2c_master_s *dev);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct i2c_ops_s g_i2c_ops =
+{
+  .transfer = am62x_i2c_transfer
+#ifdef CONFIG_I2C_RESET
+  , .reset = am62x_i2c_reset

Review Comment:
   Why is the comma on this line?



##########
arch/arm64/src/am62x/am62x_i2c.c:
##########
@@ -0,0 +1,683 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_i2c.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+#include <nuttx/debug.h>
+#include <nuttx/irq.h>
+#include <nuttx/mutex.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/i2c/i2c_master.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_i2c.h"
+#include "hardware/am62x_memorymap.h"
+#include "am62x_i2c.h"
+#include "am62x_tisci.h"
+
+#if defined(CONFIG_AM62X_I2C0) || defined(CONFIG_AM62X_I2C1) || \
+    defined(CONFIG_AM62X_I2C2) || defined(CONFIG_AM62X_I2C3)

Review Comment:
   Ditto, remove



##########
arch/arm64/src/am62x/am62x_tisci.c:
##########
@@ -0,0 +1,543 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_tisci.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mutex.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_memorymap.h"
+#include "hardware/am62x_secure_proxy.h"
+#include "hardware/am62x_tisci_proto.h"
+#include "am62x_tisci.h"
+
+#ifdef CONFIG_AM62X_TISCI
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Host id and secure-proxy thread assignment (Kconfig-tunable; defaults
+ * match the A53 HLOS host on a standard AM62x DM/TIFS boardcfg).
+ */
+
+#define AM62X_TISCI_HOST_ID    CONFIG_AM62X_TISCI_HOST_ID
+#define AM62X_TISCI_RX_THREAD  CONFIG_AM62X_TISCI_RX_THREAD
+#define AM62X_TISCI_TX_THREAD  CONFIG_AM62X_TISCI_TX_THREAD
+
+/* Bounded poll: up to ~1 s waiting on a secure-proxy thread credit */
+
+#define AM62X_TISCI_POLL_US    1
+#define AM62X_TISCI_POLL_MAX   1000000
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Serialises the single outstanding request/response transaction */
+
+static mutex_t g_tisci_lock = NXMUTEX_INITIALIZER;
+
+/* Rolling sequence number used to match responses to requests */
+
+static uint8_t g_tisci_seq;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: am62x_sproxy_wait
+ *
+ * Description:
+ *   Wait until the given secure-proxy thread has a non-zero credit count
+ *   (a free slot for TX, or a pending message for RX), or report a thread
+ *   error / timeout.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_wait(uintptr_t status_reg)
+{
+  int retries = AM62X_TISCI_POLL_MAX;
+  uint32_t status;
+
+  do
+    {
+      status = getreg32(status_reg);
+      if ((status & AM62X_SEC_PROXY_RT_ERR) != 0)
+        {
+          return -EIO;
+        }
+
+      if ((status & AM62X_SEC_PROXY_RT_CNT_MASK) != 0)
+        {
+          return OK;
+        }
+
+      up_udelay(AM62X_TISCI_POLL_US);
+    }
+  while (--retries > 0);
+
+  return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_send
+ *
+ * Description:
+ *   Push a message (up to 60 bytes) onto the TX thread.  The message is
+ *   zero-padded to the full 15-word window; the write to the final word
+ *   (offset 0x3c) commits the transfer to the firmware.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_send(const void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_TX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_TX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  memset(buf, 0, sizeof(buf));

Review Comment:
   What is the point?



##########
arch/arm64/src/am62x/am62x_tisci.c:
##########
@@ -0,0 +1,543 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_tisci.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mutex.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_memorymap.h"
+#include "hardware/am62x_secure_proxy.h"
+#include "hardware/am62x_tisci_proto.h"
+#include "am62x_tisci.h"
+
+#ifdef CONFIG_AM62X_TISCI
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Host id and secure-proxy thread assignment (Kconfig-tunable; defaults
+ * match the A53 HLOS host on a standard AM62x DM/TIFS boardcfg).
+ */
+
+#define AM62X_TISCI_HOST_ID    CONFIG_AM62X_TISCI_HOST_ID
+#define AM62X_TISCI_RX_THREAD  CONFIG_AM62X_TISCI_RX_THREAD
+#define AM62X_TISCI_TX_THREAD  CONFIG_AM62X_TISCI_TX_THREAD
+
+/* Bounded poll: up to ~1 s waiting on a secure-proxy thread credit */
+
+#define AM62X_TISCI_POLL_US    1
+#define AM62X_TISCI_POLL_MAX   1000000
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Serialises the single outstanding request/response transaction */
+
+static mutex_t g_tisci_lock = NXMUTEX_INITIALIZER;
+
+/* Rolling sequence number used to match responses to requests */
+
+static uint8_t g_tisci_seq;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: am62x_sproxy_wait
+ *
+ * Description:
+ *   Wait until the given secure-proxy thread has a non-zero credit count
+ *   (a free slot for TX, or a pending message for RX), or report a thread
+ *   error / timeout.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_wait(uintptr_t status_reg)
+{
+  int retries = AM62X_TISCI_POLL_MAX;
+  uint32_t status;
+
+  do
+    {
+      status = getreg32(status_reg);
+      if ((status & AM62X_SEC_PROXY_RT_ERR) != 0)
+        {
+          return -EIO;
+        }
+
+      if ((status & AM62X_SEC_PROXY_RT_CNT_MASK) != 0)
+        {
+          return OK;
+        }
+
+      up_udelay(AM62X_TISCI_POLL_US);
+    }
+  while (--retries > 0);
+
+  return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_send
+ *
+ * Description:
+ *   Push a message (up to 60 bytes) onto the TX thread.  The message is
+ *   zero-padded to the full 15-word window; the write to the final word
+ *   (offset 0x3c) commits the transfer to the firmware.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_send(const void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_TX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_TX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  memset(buf, 0, sizeof(buf));
+  memcpy(buf, msg, len);
+
+  /* Write all 15 words in ascending order; the last (offset 0x3c) commits. */
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      putreg32(buf[i], data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_recv
+ *
+ * Description:
+ *   Read a response from the RX thread.  All 15 words are read so the
+ *   final-word read marks the message consumed.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_recv(void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      buf[i] = getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  memcpy(msg, buf, len);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_drain
+ *
+ * Description:
+ *   Discard any stale message pending on the RX thread before a new
+ *   transaction, so an orphaned response cannot desynchronise sequencing.
+ *
+ ****************************************************************************/
+
+static void am62x_sproxy_drain(void)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  int guard = AM62X_SEC_PROXY_MSG_WORDS + 1;
+  uint32_t s;
+  int i;
+
+  while (guard-- > 0)
+    {
+      s = getreg32(status);
+      if ((s & AM62X_SEC_PROXY_RT_ERR) != 0 ||
+          (s & AM62X_SEC_PROXY_RT_CNT_MASK) == 0)
+        {
+          break;
+        }
+
+      for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+        {
+          getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_xfer
+ *
+ * Description:
+ *   Run one synchronous TISCI request/response.  Fills the header host, seq,
+ *   and ACK-on-processed flag, sends the request, reads the response, and
+ *   validates the ACK and matching sequence number.
+ *
+ ****************************************************************************/
+
+static int am62x_tisci_xfer(struct ti_sci_msg_hdr *req, size_t req_sz,
+                            struct ti_sci_msg_hdr *resp, size_t resp_sz)
+{
+  uint8_t seq;
+  int ret;
+
+  ret = nxmutex_lock(&g_tisci_lock);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  seq = ++g_tisci_seq;
+  req->host  = AM62X_TISCI_HOST_ID;
+  req->seq   = seq;
+  req->flags |= TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
+
+  am62x_sproxy_drain();
+
+  ret = am62x_sproxy_send(req, req_sz);
+  if (ret == OK)
+    {
+      ret = am62x_sproxy_recv(resp, resp_sz);
+    }
+
+  nxmutex_unlock(&g_tisci_lock);
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if ((resp->flags & TI_SCI_FLAG_RESP_GENERIC_ACK) == 0)
+    {
+      return -EIO;   /* firmware NAK */
+    }
+
+  if (resp->seq != seq)
+    {
+      return -EPROTO;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_clkid
+ *
+ * Description:
+ *   Encode a clock id into the 8-bit clk_id / 32-bit clk_id_32 pair used by
+ *   the clock messages.
+ *
+ ****************************************************************************/
+
+static void am62x_tisci_clkid(uint32_t clkid, uint8_t *clk_id,
+                              uint32_t *clk_id_32)
+{
+  if (clkid < TI_SCI_CLOCK_ID_INDIRECT)
+    {
+      *clk_id    = (uint8_t)clkid;
+      *clk_id_32 = 0;
+    }
+  else
+    {
+      *clk_id    = TI_SCI_CLOCK_ID_INDIRECT;
+      *clk_id_32 = clkid;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int am62x_tisci_get_version(struct am62x_tisci_version_s *ver)
+{
+  struct ti_sci_msg_hdr req;
+  struct ti_sci_msg_resp_version resp;
+  int ret;
+
+  memset(&req, 0, sizeof(req));
+  memset(&resp, 0, sizeof(resp));

Review Comment:
   Are these necessary?



##########
arch/arm64/src/am62x/CMakeLists.txt:
##########
@@ -22,7 +22,11 @@
 
 # AM62x SoC sources that are always compiled
 
-list(APPEND SRCS am62x_boot.c am62x_16550serial.c)
+list(APPEND SRCS am62x_boot.c am62x_16550serial.c am62x_gpio.c am62x_i2c.c)

Review Comment:
   GPIO and I2C files should be conditionally included only.



##########
arch/arm64/src/am62x/Kconfig:
##########
@@ -7,6 +7,94 @@
 
 if ARCH_CHIP_AM62X
 
-comment "AM62x peripheral selection is provided by board defconfig for now."
+menu "AM62x peripheral support"
+
+config AM62X_TISCI
+       bool "TISCI system controller (DM/TIFS) client"
+       default n
+       ---help---
+               Enable the AM62x TISCI client.  On K3 SoCs the A53 does not own
+               device power, clocks, resets, or interrupt routing; those are
+               requested from the DM/TIFS firmware over the TISCI protocol via 
the
+               secure-proxy mailbox.  This driver provides the request helpers 
used
+               by peripheral drivers to power on a block, enable its functional
+               clock, release resets, and route its interrupt to the GIC.
+
+if AM62X_TISCI
+
+config AM62X_TISCI_HOST_ID
+       int "TISCI host ID"
+       default 12
+       ---help---
+               Host ID this core presents to the DM/TIFS firmware.  Must match 
the
+               host allocation in the firmware boardcfg.  12 is the standard 
A53
+               HLOS host on AM62x.
+
+config AM62X_TISCI_RX_THREAD
+       int "Secure proxy RX (response) thread"
+       default 12
+       ---help---
+               Secure-proxy thread the firmware uses to send responses back to 
this
+               host.
+
+config AM62X_TISCI_TX_THREAD
+       int "Secure proxy TX (request) thread"
+       default 13
+       ---help---
+               Secure-proxy thread this host uses to send requests to the 
firmware.
+
+endif # AM62X_TISCI
+
+config AM62X_GPIO
+       bool "GPIO support"
+       default n
+       ---help---
+               Enable the AM62x main-domain GPIO controller driver, including
+               basic GPIO input/output operations, pad-mux helper support, and
+               per-pin interrupt callback dispatch for GPIO0/GPIO1.
+
+config AM62X_GPIO_IRQ
+       bool "GPIO interrupt (GIC) delivery"
+       depends on AM62X_GPIO
+       default n
+       ---help---
+               Enable per-bank GPIO interrupt delivery through the GIC.  On 
AM62x
+               the GPIO bank interrupts are routed through the main GPIO 
interrupt
+               router, which must be programmed over TISCI (RM_IRQ_SET) before 
the
+               GIC input line is valid.  Until that routing is implemented, 
leave
+               this disabled: enabling an unrouted GIC line faults at boot.  
GPIO
+               input/output and the callback API still work without it.
+
+config AM62X_I2C0
+       bool "I2C0 support"
+       depends on I2C
+       default n
+
+config AM62X_I2C1
+       bool "I2C1 support"
+       depends on I2C
+       default n
+
+config AM62X_I2C2
+       bool "I2C2 support"
+       depends on I2C
+       default n
+
+config AM62X_I2C3
+       bool "I2C3 support"
+       depends on I2C
+       default n
+
+config AM62X_I2CTIMEOSEC
+       int "I2C transfer timeout seconds"
+       default 0
+       depends on AM62X_I2C0 || AM62X_I2C1 || AM62X_I2C2 || AM62X_I2C3
+
+config AM62X_I2CTIMEOMS
+       int "I2C transfer timeout milliseconds"
+       default 500
+       depends on AM62X_I2C0 || AM62X_I2C1 || AM62X_I2C2 || AM62X_I2C3

Review Comment:
   Why have two options? Can we just use milliseconds instead? A several second 
timeout is a) impractical and b) can be represented with milliseconds.



##########
arch/arm64/src/am62x/Make.defs:
##########
@@ -29,6 +29,13 @@ include common/Make.defs
 
 CHIP_CSRCS  = am62x_boot.c
 CHIP_CSRCS += am62x_16550serial.c
+CHIP_CSRCS += am62x_gpio.c
+CHIP_CSRCS += am62x_i2c.c

Review Comment:
   Should be conditionally included only.



##########
arch/arm64/src/am62x/am62x_tisci.c:
##########
@@ -0,0 +1,543 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_tisci.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mutex.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_memorymap.h"
+#include "hardware/am62x_secure_proxy.h"
+#include "hardware/am62x_tisci_proto.h"
+#include "am62x_tisci.h"
+
+#ifdef CONFIG_AM62X_TISCI
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Host id and secure-proxy thread assignment (Kconfig-tunable; defaults
+ * match the A53 HLOS host on a standard AM62x DM/TIFS boardcfg).
+ */
+
+#define AM62X_TISCI_HOST_ID    CONFIG_AM62X_TISCI_HOST_ID
+#define AM62X_TISCI_RX_THREAD  CONFIG_AM62X_TISCI_RX_THREAD
+#define AM62X_TISCI_TX_THREAD  CONFIG_AM62X_TISCI_TX_THREAD
+
+/* Bounded poll: up to ~1 s waiting on a secure-proxy thread credit */
+
+#define AM62X_TISCI_POLL_US    1
+#define AM62X_TISCI_POLL_MAX   1000000
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Serialises the single outstanding request/response transaction */
+
+static mutex_t g_tisci_lock = NXMUTEX_INITIALIZER;
+
+/* Rolling sequence number used to match responses to requests */
+
+static uint8_t g_tisci_seq;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: am62x_sproxy_wait
+ *
+ * Description:
+ *   Wait until the given secure-proxy thread has a non-zero credit count
+ *   (a free slot for TX, or a pending message for RX), or report a thread
+ *   error / timeout.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_wait(uintptr_t status_reg)
+{
+  int retries = AM62X_TISCI_POLL_MAX;
+  uint32_t status;
+
+  do
+    {
+      status = getreg32(status_reg);
+      if ((status & AM62X_SEC_PROXY_RT_ERR) != 0)
+        {
+          return -EIO;
+        }
+
+      if ((status & AM62X_SEC_PROXY_RT_CNT_MASK) != 0)
+        {
+          return OK;
+        }
+
+      up_udelay(AM62X_TISCI_POLL_US);
+    }
+  while (--retries > 0);
+
+  return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_send
+ *
+ * Description:
+ *   Push a message (up to 60 bytes) onto the TX thread.  The message is
+ *   zero-padded to the full 15-word window; the write to the final word
+ *   (offset 0x3c) commits the transfer to the firmware.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_send(const void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_TX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_TX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  memset(buf, 0, sizeof(buf));
+  memcpy(buf, msg, len);
+
+  /* Write all 15 words in ascending order; the last (offset 0x3c) commits. */
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      putreg32(buf[i], data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_recv
+ *
+ * Description:
+ *   Read a response from the RX thread.  All 15 words are read so the
+ *   final-word read marks the message consumed.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_recv(void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      buf[i] = getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  memcpy(msg, buf, len);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_drain
+ *
+ * Description:
+ *   Discard any stale message pending on the RX thread before a new
+ *   transaction, so an orphaned response cannot desynchronise sequencing.
+ *
+ ****************************************************************************/
+
+static void am62x_sproxy_drain(void)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  int guard = AM62X_SEC_PROXY_MSG_WORDS + 1;
+  uint32_t s;
+  int i;
+
+  while (guard-- > 0)
+    {
+      s = getreg32(status);
+      if ((s & AM62X_SEC_PROXY_RT_ERR) != 0 ||
+          (s & AM62X_SEC_PROXY_RT_CNT_MASK) == 0)
+        {
+          break;
+        }
+
+      for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+        {
+          getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_xfer
+ *
+ * Description:
+ *   Run one synchronous TISCI request/response.  Fills the header host, seq,
+ *   and ACK-on-processed flag, sends the request, reads the response, and
+ *   validates the ACK and matching sequence number.
+ *
+ ****************************************************************************/
+
+static int am62x_tisci_xfer(struct ti_sci_msg_hdr *req, size_t req_sz,
+                            struct ti_sci_msg_hdr *resp, size_t resp_sz)
+{
+  uint8_t seq;
+  int ret;
+
+  ret = nxmutex_lock(&g_tisci_lock);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  seq = ++g_tisci_seq;
+  req->host  = AM62X_TISCI_HOST_ID;
+  req->seq   = seq;
+  req->flags |= TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
+
+  am62x_sproxy_drain();
+
+  ret = am62x_sproxy_send(req, req_sz);
+  if (ret == OK)
+    {
+      ret = am62x_sproxy_recv(resp, resp_sz);
+    }
+
+  nxmutex_unlock(&g_tisci_lock);
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if ((resp->flags & TI_SCI_FLAG_RESP_GENERIC_ACK) == 0)
+    {
+      return -EIO;   /* firmware NAK */
+    }
+
+  if (resp->seq != seq)
+    {
+      return -EPROTO;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_clkid
+ *
+ * Description:
+ *   Encode a clock id into the 8-bit clk_id / 32-bit clk_id_32 pair used by
+ *   the clock messages.
+ *
+ ****************************************************************************/
+
+static void am62x_tisci_clkid(uint32_t clkid, uint8_t *clk_id,
+                              uint32_t *clk_id_32)
+{
+  if (clkid < TI_SCI_CLOCK_ID_INDIRECT)
+    {
+      *clk_id    = (uint8_t)clkid;
+      *clk_id_32 = 0;
+    }
+  else
+    {
+      *clk_id    = TI_SCI_CLOCK_ID_INDIRECT;
+      *clk_id_32 = clkid;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int am62x_tisci_get_version(struct am62x_tisci_version_s *ver)
+{
+  struct ti_sci_msg_hdr req;
+  struct ti_sci_msg_resp_version resp;
+  int ret;
+
+  memset(&req, 0, sizeof(req));
+  memset(&resp, 0, sizeof(resp));
+  req.type = TI_SCI_MSG_VERSION;
+
+  ret = am62x_tisci_xfer(&req, sizeof(req), &resp.hdr, sizeof(resp));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (ver != NULL)
+    {
+      ver->firmware_revision = resp.firmware_revision;
+      ver->abi_major = resp.abi_major;
+      ver->abi_minor = resp.abi_minor;
+      memcpy(ver->firmware_description, resp.firmware_description,
+             sizeof(resp.firmware_description));
+      ver->firmware_description[sizeof(resp.firmware_description)] = '\0';
+    }
+
+  return OK;
+}
+
+int am62x_tisci_set_device_state(uint32_t devid, uint8_t state)
+{
+  struct ti_sci_msg_req_set_device_state req;
+  struct ti_sci_msg_hdr resp;
+
+  memset(&req, 0, sizeof(req));

Review Comment:
   Ditto here and everywhere else this is done



##########
boards/arm64/am62x/pocketbeagle2/src/pocketbeagle2_bringup.c:
##########
@@ -25,17 +25,73 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
-#include <nuttx/kmalloc.h>
+
 #include <sys/types.h>
 #include <syslog.h>
 #include <errno.h>
 
+#include <nuttx/i2c/i2c_master.h>
+
+#include "am62x_gpio.h"
+#include "am62x_i2c.h"
+#include "am62x_tisci.h"
 #include "pocketbeagle2.h"
 
 #ifdef CONFIG_FS_PROCFS
 #  include <nuttx/fs/fs.h>
 #endif
 
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#if defined(CONFIG_I2C_DRIVER) && \
+    (defined(CONFIG_AM62X_I2C0) || defined(CONFIG_AM62X_I2C2))
+static int am62x_i2cdev_register(int bus)
+{
+  struct i2c_master_s *i2c;
+  int ret;
+
+  i2c = am62x_i2cbus_initialize(bus);
+  if (i2c == NULL)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize I2C%d\n", bus);
+      return -ENODEV;
+    }
+
+  ret = i2c_register(i2c, bus);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to register /dev/i2c%d: %d\n",
+             bus, ret);
+      am62x_i2cbus_uninitialize(i2c);
+    }
+
+  return ret;
+}
+#endif
+
+#if defined(CONFIG_AM62X_I2C0) || defined(CONFIG_AM62X_I2C2)
+static void pocketbeagle2_i2c_pinmux(void)
+{
+#ifdef CONFIG_AM62X_I2C0
+  uint32_t i2c0_cfg = AM62X_PADCFG_RXACTIVE | AM62X_PADCFG_PULL_UP |
+                      AM62X_PADCFG_MUXMODE(0);
+
+  (void)am62x_pinmux_configure(0x01e0, i2c0_cfg); /* I2C0_SCL */

Review Comment:
   Why ignore the result here?



##########
arch/arm64/src/am62x/am62x_tisci.c:
##########
@@ -0,0 +1,543 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_tisci.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mutex.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_memorymap.h"
+#include "hardware/am62x_secure_proxy.h"
+#include "hardware/am62x_tisci_proto.h"
+#include "am62x_tisci.h"
+
+#ifdef CONFIG_AM62X_TISCI
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Host id and secure-proxy thread assignment (Kconfig-tunable; defaults
+ * match the A53 HLOS host on a standard AM62x DM/TIFS boardcfg).
+ */
+
+#define AM62X_TISCI_HOST_ID    CONFIG_AM62X_TISCI_HOST_ID
+#define AM62X_TISCI_RX_THREAD  CONFIG_AM62X_TISCI_RX_THREAD
+#define AM62X_TISCI_TX_THREAD  CONFIG_AM62X_TISCI_TX_THREAD
+
+/* Bounded poll: up to ~1 s waiting on a secure-proxy thread credit */
+
+#define AM62X_TISCI_POLL_US    1
+#define AM62X_TISCI_POLL_MAX   1000000
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Serialises the single outstanding request/response transaction */
+
+static mutex_t g_tisci_lock = NXMUTEX_INITIALIZER;
+
+/* Rolling sequence number used to match responses to requests */
+
+static uint8_t g_tisci_seq;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: am62x_sproxy_wait
+ *
+ * Description:
+ *   Wait until the given secure-proxy thread has a non-zero credit count
+ *   (a free slot for TX, or a pending message for RX), or report a thread
+ *   error / timeout.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_wait(uintptr_t status_reg)
+{
+  int retries = AM62X_TISCI_POLL_MAX;
+  uint32_t status;
+
+  do
+    {
+      status = getreg32(status_reg);
+      if ((status & AM62X_SEC_PROXY_RT_ERR) != 0)
+        {
+          return -EIO;
+        }
+
+      if ((status & AM62X_SEC_PROXY_RT_CNT_MASK) != 0)
+        {
+          return OK;
+        }
+
+      up_udelay(AM62X_TISCI_POLL_US);
+    }
+  while (--retries > 0);
+
+  return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_send
+ *
+ * Description:
+ *   Push a message (up to 60 bytes) onto the TX thread.  The message is
+ *   zero-padded to the full 15-word window; the write to the final word
+ *   (offset 0x3c) commits the transfer to the firmware.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_send(const void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_TX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_TX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  memset(buf, 0, sizeof(buf));
+  memcpy(buf, msg, len);
+
+  /* Write all 15 words in ascending order; the last (offset 0x3c) commits. */
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      putreg32(buf[i], data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_recv
+ *
+ * Description:
+ *   Read a response from the RX thread.  All 15 words are read so the
+ *   final-word read marks the message consumed.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_recv(void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      buf[i] = getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  memcpy(msg, buf, len);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_drain
+ *
+ * Description:
+ *   Discard any stale message pending on the RX thread before a new
+ *   transaction, so an orphaned response cannot desynchronise sequencing.
+ *
+ ****************************************************************************/
+
+static void am62x_sproxy_drain(void)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  int guard = AM62X_SEC_PROXY_MSG_WORDS + 1;
+  uint32_t s;
+  int i;
+
+  while (guard-- > 0)
+    {
+      s = getreg32(status);
+      if ((s & AM62X_SEC_PROXY_RT_ERR) != 0 ||
+          (s & AM62X_SEC_PROXY_RT_CNT_MASK) == 0)
+        {
+          break;
+        }
+
+      for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+        {
+          getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_xfer
+ *
+ * Description:
+ *   Run one synchronous TISCI request/response.  Fills the header host, seq,
+ *   and ACK-on-processed flag, sends the request, reads the response, and
+ *   validates the ACK and matching sequence number.
+ *
+ ****************************************************************************/
+
+static int am62x_tisci_xfer(struct ti_sci_msg_hdr *req, size_t req_sz,
+                            struct ti_sci_msg_hdr *resp, size_t resp_sz)
+{
+  uint8_t seq;
+  int ret;
+
+  ret = nxmutex_lock(&g_tisci_lock);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  seq = ++g_tisci_seq;
+  req->host  = AM62X_TISCI_HOST_ID;
+  req->seq   = seq;
+  req->flags |= TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
+
+  am62x_sproxy_drain();
+
+  ret = am62x_sproxy_send(req, req_sz);
+  if (ret == OK)
+    {
+      ret = am62x_sproxy_recv(resp, resp_sz);
+    }
+
+  nxmutex_unlock(&g_tisci_lock);
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if ((resp->flags & TI_SCI_FLAG_RESP_GENERIC_ACK) == 0)
+    {
+      return -EIO;   /* firmware NAK */
+    }
+
+  if (resp->seq != seq)
+    {
+      return -EPROTO;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_clkid
+ *
+ * Description:
+ *   Encode a clock id into the 8-bit clk_id / 32-bit clk_id_32 pair used by
+ *   the clock messages.
+ *
+ ****************************************************************************/
+
+static void am62x_tisci_clkid(uint32_t clkid, uint8_t *clk_id,
+                              uint32_t *clk_id_32)
+{
+  if (clkid < TI_SCI_CLOCK_ID_INDIRECT)
+    {
+      *clk_id    = (uint8_t)clkid;
+      *clk_id_32 = 0;
+    }
+  else
+    {
+      *clk_id    = TI_SCI_CLOCK_ID_INDIRECT;
+      *clk_id_32 = clkid;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int am62x_tisci_get_version(struct am62x_tisci_version_s *ver)
+{
+  struct ti_sci_msg_hdr req;
+  struct ti_sci_msg_resp_version resp;
+  int ret;
+
+  memset(&req, 0, sizeof(req));
+  memset(&resp, 0, sizeof(resp));
+  req.type = TI_SCI_MSG_VERSION;
+
+  ret = am62x_tisci_xfer(&req, sizeof(req), &resp.hdr, sizeof(resp));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (ver != NULL)
+    {
+      ver->firmware_revision = resp.firmware_revision;
+      ver->abi_major = resp.abi_major;
+      ver->abi_minor = resp.abi_minor;
+      memcpy(ver->firmware_description, resp.firmware_description,
+             sizeof(resp.firmware_description));
+      ver->firmware_description[sizeof(resp.firmware_description)] = '\0';
+    }
+
+  return OK;
+}
+
+int am62x_tisci_set_device_state(uint32_t devid, uint8_t state)
+{
+  struct ti_sci_msg_req_set_device_state req;
+  struct ti_sci_msg_hdr resp;
+
+  memset(&req, 0, sizeof(req));
+  req.hdr.type = TI_SCI_MSG_SET_DEVICE_STATE;
+  req.id = devid;
+  req.state = state;
+
+  return am62x_tisci_xfer(&req.hdr, sizeof(req), &resp, sizeof(resp));
+}
+
+int am62x_tisci_get_device_state(uint32_t devid, uint8_t *current_state)
+{
+  struct ti_sci_msg_req_get_device_state req;
+  struct ti_sci_msg_resp_get_device_state resp;
+  int ret;
+
+  memset(&req, 0, sizeof(req));
+  memset(&resp, 0, sizeof(resp));
+  req.hdr.type = TI_SCI_MSG_GET_DEVICE_STATE;
+  req.id = devid;
+
+  ret = am62x_tisci_xfer(&req.hdr, sizeof(req), &resp.hdr, sizeof(resp));
+  if (ret == OK && current_state != NULL)
+    {
+      *current_state = resp.current_state;
+    }
+
+  return ret;
+}
+
+int am62x_tisci_dev_on(uint32_t devid)
+{
+  return am62x_tisci_set_device_state(devid, MSG_DEVICE_SW_STATE_ON);
+}
+
+int am62x_tisci_dev_off(uint32_t devid)
+{
+  return am62x_tisci_set_device_state(devid, MSG_DEVICE_SW_STATE_AUTO_OFF);
+}

Review Comment:
   Why not just call the inner function directly? This is not very useful.



##########
boards/arm64/am62x/pocketbeagle2/src/pocketbeagle2_gpio.c:
##########
@@ -0,0 +1,161 @@
+/****************************************************************************
+ * boards/arm64/am62x/pocketbeagle2/src/pocketbeagle2_gpio.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <nuttx/ioexpander/gpio.h>
+
+#include <arch/board/board.h>
+
+#include "am62x_gpio.h"
+#include "pocketbeagle2.h"
+
+#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PB2_GPIO_OUT_FLAGS       (AM62X_GPIO_OUTPUT | AM62X_GPIO_PULL_NONE)
+#define PB2_LED_PADCFG           (AM62X_PADCFG_PULL_DISABLE | \
+                                  AM62X_PADCFG_MUXMODE(7))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct pocketbeagle2_gpio_dev_s
+{
+  struct gpio_dev_s gpio;
+  uint8_t id;
+};
+
+struct pocketbeagle2_gpio_pin_s
+{
+  gpio_pinset_t pinset;
+  uintptr_t padcfg;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int gpout_read(struct gpio_dev_s *dev, bool *value);
+static int gpout_write(struct gpio_dev_s *dev, bool value);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct gpio_operations_s gpout_ops =
+{
+  .go_read = gpout_read,
+  .go_write = gpout_write,
+  .go_attach = NULL,
+  .go_enable = NULL,
+};
+
+static const struct pocketbeagle2_gpio_pin_s g_gpiooutputs[BOARD_NGPIOOUT] =
+{
+  { AM62X_GPIO_PIN(0, 3) | PB2_GPIO_OUT_FLAGS, 0x000c },

Review Comment:
   Should these magic padcfg numbers be replaced with macros for clarity?



##########
arch/arm64/src/am62x/am62x_tisci.c:
##########
@@ -0,0 +1,543 @@
+/****************************************************************************
+ * arch/arm64/src/am62x/am62x_tisci.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mutex.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/am62x_memorymap.h"
+#include "hardware/am62x_secure_proxy.h"
+#include "hardware/am62x_tisci_proto.h"
+#include "am62x_tisci.h"
+
+#ifdef CONFIG_AM62X_TISCI
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Host id and secure-proxy thread assignment (Kconfig-tunable; defaults
+ * match the A53 HLOS host on a standard AM62x DM/TIFS boardcfg).
+ */
+
+#define AM62X_TISCI_HOST_ID    CONFIG_AM62X_TISCI_HOST_ID
+#define AM62X_TISCI_RX_THREAD  CONFIG_AM62X_TISCI_RX_THREAD
+#define AM62X_TISCI_TX_THREAD  CONFIG_AM62X_TISCI_TX_THREAD
+
+/* Bounded poll: up to ~1 s waiting on a secure-proxy thread credit */
+
+#define AM62X_TISCI_POLL_US    1
+#define AM62X_TISCI_POLL_MAX   1000000
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Serialises the single outstanding request/response transaction */
+
+static mutex_t g_tisci_lock = NXMUTEX_INITIALIZER;
+
+/* Rolling sequence number used to match responses to requests */
+
+static uint8_t g_tisci_seq;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: am62x_sproxy_wait
+ *
+ * Description:
+ *   Wait until the given secure-proxy thread has a non-zero credit count
+ *   (a free slot for TX, or a pending message for RX), or report a thread
+ *   error / timeout.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_wait(uintptr_t status_reg)
+{
+  int retries = AM62X_TISCI_POLL_MAX;
+  uint32_t status;
+
+  do
+    {
+      status = getreg32(status_reg);
+      if ((status & AM62X_SEC_PROXY_RT_ERR) != 0)
+        {
+          return -EIO;
+        }
+
+      if ((status & AM62X_SEC_PROXY_RT_CNT_MASK) != 0)
+        {
+          return OK;
+        }
+
+      up_udelay(AM62X_TISCI_POLL_US);
+    }
+  while (--retries > 0);
+
+  return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_send
+ *
+ * Description:
+ *   Push a message (up to 60 bytes) onto the TX thread.  The message is
+ *   zero-padded to the full 15-word window; the write to the final word
+ *   (offset 0x3c) commits the transfer to the firmware.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_send(const void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_TX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_TX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  memset(buf, 0, sizeof(buf));
+  memcpy(buf, msg, len);
+
+  /* Write all 15 words in ascending order; the last (offset 0x3c) commits. */
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      putreg32(buf[i], data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_recv
+ *
+ * Description:
+ *   Read a response from the RX thread.  All 15 words are read so the
+ *   final-word read marks the message consumed.
+ *
+ ****************************************************************************/
+
+static int am62x_sproxy_recv(void *msg, size_t len)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  uint32_t buf[AM62X_SEC_PROXY_MSG_WORDS];
+  int ret;
+  int i;
+
+  if (len > AM62X_SEC_PROXY_MAX_MSG_SIZE)
+    {
+      return -EINVAL;
+    }
+
+  ret = am62x_sproxy_wait(status);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+    {
+      buf[i] = getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+    }
+
+  memcpy(msg, buf, len);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_sproxy_drain
+ *
+ * Description:
+ *   Discard any stale message pending on the RX thread before a new
+ *   transaction, so an orphaned response cannot desynchronise sequencing.
+ *
+ ****************************************************************************/
+
+static void am62x_sproxy_drain(void)
+{
+  uintptr_t data = AM62X_SEC_PROXY_DATA(AM62X_TISCI_RX_THREAD);
+  uintptr_t status = AM62X_SEC_PROXY_RT(AM62X_TISCI_RX_THREAD) +
+                     AM62X_SEC_PROXY_RT_STATUS;
+  int guard = AM62X_SEC_PROXY_MSG_WORDS + 1;
+  uint32_t s;
+  int i;
+
+  while (guard-- > 0)
+    {
+      s = getreg32(status);
+      if ((s & AM62X_SEC_PROXY_RT_ERR) != 0 ||
+          (s & AM62X_SEC_PROXY_RT_CNT_MASK) == 0)
+        {
+          break;
+        }
+
+      for (i = 0; i < AM62X_SEC_PROXY_MSG_WORDS; i++)
+        {
+          getreg32(data + AM62X_SEC_PROXY_DATA_START + i * 4);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_xfer
+ *
+ * Description:
+ *   Run one synchronous TISCI request/response.  Fills the header host, seq,
+ *   and ACK-on-processed flag, sends the request, reads the response, and
+ *   validates the ACK and matching sequence number.
+ *
+ ****************************************************************************/
+
+static int am62x_tisci_xfer(struct ti_sci_msg_hdr *req, size_t req_sz,
+                            struct ti_sci_msg_hdr *resp, size_t resp_sz)
+{
+  uint8_t seq;
+  int ret;
+
+  ret = nxmutex_lock(&g_tisci_lock);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  seq = ++g_tisci_seq;
+  req->host  = AM62X_TISCI_HOST_ID;
+  req->seq   = seq;
+  req->flags |= TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
+
+  am62x_sproxy_drain();
+
+  ret = am62x_sproxy_send(req, req_sz);
+  if (ret == OK)
+    {
+      ret = am62x_sproxy_recv(resp, resp_sz);
+    }
+
+  nxmutex_unlock(&g_tisci_lock);
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if ((resp->flags & TI_SCI_FLAG_RESP_GENERIC_ACK) == 0)
+    {
+      return -EIO;   /* firmware NAK */
+    }
+
+  if (resp->seq != seq)
+    {
+      return -EPROTO;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: am62x_tisci_clkid
+ *
+ * Description:
+ *   Encode a clock id into the 8-bit clk_id / 32-bit clk_id_32 pair used by
+ *   the clock messages.
+ *
+ ****************************************************************************/
+
+static void am62x_tisci_clkid(uint32_t clkid, uint8_t *clk_id,
+                              uint32_t *clk_id_32)
+{
+  if (clkid < TI_SCI_CLOCK_ID_INDIRECT)
+    {
+      *clk_id    = (uint8_t)clkid;
+      *clk_id_32 = 0;
+    }
+  else
+    {
+      *clk_id    = TI_SCI_CLOCK_ID_INDIRECT;
+      *clk_id_32 = clkid;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int am62x_tisci_get_version(struct am62x_tisci_version_s *ver)
+{
+  struct ti_sci_msg_hdr req;
+  struct ti_sci_msg_resp_version resp;
+  int ret;
+
+  memset(&req, 0, sizeof(req));
+  memset(&resp, 0, sizeof(resp));
+  req.type = TI_SCI_MSG_VERSION;
+
+  ret = am62x_tisci_xfer(&req, sizeof(req), &resp.hdr, sizeof(resp));
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (ver != NULL)
+    {
+      ver->firmware_revision = resp.firmware_revision;
+      ver->abi_major = resp.abi_major;
+      ver->abi_minor = resp.abi_minor;
+      memcpy(ver->firmware_description, resp.firmware_description,
+             sizeof(resp.firmware_description));
+      ver->firmware_description[sizeof(resp.firmware_description)] = '\0';
+    }
+
+  return OK;
+}
+
+int am62x_tisci_set_device_state(uint32_t devid, uint8_t state)
+{
+  struct ti_sci_msg_req_set_device_state req;
+  struct ti_sci_msg_hdr resp;
+
+  memset(&req, 0, sizeof(req));
+  req.hdr.type = TI_SCI_MSG_SET_DEVICE_STATE;
+  req.id = devid;
+  req.state = state;
+
+  return am62x_tisci_xfer(&req.hdr, sizeof(req), &resp, sizeof(resp));
+}
+
+int am62x_tisci_get_device_state(uint32_t devid, uint8_t *current_state)
+{
+  struct ti_sci_msg_req_get_device_state req;
+  struct ti_sci_msg_resp_get_device_state resp;
+  int ret;
+
+  memset(&req, 0, sizeof(req));
+  memset(&resp, 0, sizeof(resp));
+  req.hdr.type = TI_SCI_MSG_GET_DEVICE_STATE;
+  req.id = devid;
+
+  ret = am62x_tisci_xfer(&req.hdr, sizeof(req), &resp.hdr, sizeof(resp));
+  if (ret == OK && current_state != NULL)
+    {
+      *current_state = resp.current_state;
+    }
+
+  return ret;
+}
+
+int am62x_tisci_dev_on(uint32_t devid)
+{
+  return am62x_tisci_set_device_state(devid, MSG_DEVICE_SW_STATE_ON);
+}
+
+int am62x_tisci_dev_off(uint32_t devid)
+{
+  return am62x_tisci_set_device_state(devid, MSG_DEVICE_SW_STATE_AUTO_OFF);
+}
+
+int am62x_tisci_module_enable(uint32_t devid, uint32_t clkid)
+{
+  int ret;
+
+  ret = am62x_tisci_dev_on(devid);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = am62x_tisci_set_device_resets(devid, 0);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = am62x_tisci_clk_enable(devid, clkid);
+  return ret;
+}
+
+int am62x_tisci_set_device_resets(uint32_t devid, uint32_t resets)
+{
+  struct ti_sci_msg_req_set_device_resets req;
+  struct ti_sci_msg_hdr resp;
+
+  memset(&req, 0, sizeof(req));
+  req.hdr.type = TI_SCI_MSG_SET_DEVICE_RESETS;
+  req.id = devid;
+  req.resets = resets;
+
+  return am62x_tisci_xfer(&req.hdr, sizeof(req), &resp, sizeof(resp));
+}
+
+int am62x_tisci_set_clock_state(uint32_t devid, uint32_t clkid,
+                                uint8_t state)
+{
+  struct ti_sci_msg_req_set_clock_state req;
+  struct ti_sci_msg_hdr resp;
+  uint8_t clk_id;
+  uint32_t clk_id_32;
+
+  memset(&req, 0, sizeof(req));
+  req.hdr.type = TI_SCI_MSG_SET_CLOCK_STATE;
+  req.dev_id = devid;
+  req.request_state = state;
+  am62x_tisci_clkid(clkid, &clk_id, &clk_id_32);
+  req.clk_id = clk_id;
+  req.clk_id_32 = clk_id_32;
+
+  return am62x_tisci_xfer(&req.hdr, sizeof(req), &resp, sizeof(resp));
+}
+
+int am62x_tisci_clk_enable(uint32_t devid, uint32_t clkid)
+{
+  return am62x_tisci_set_clock_state(devid, clkid, MSG_CLOCK_SW_STATE_REQ);
+}
+
+int am62x_tisci_set_clock_freq(uint32_t devid, uint32_t clkid,
+                               uint64_t freq_hz)
+{
+  struct ti_sci_msg_req_set_clock_freq req;
+  struct ti_sci_msg_hdr resp;
+  uint8_t clk_id;
+  uint32_t clk_id_32;
+
+  memset(&req, 0, sizeof(req));
+  req.hdr.type = TI_SCI_MSG_SET_CLOCK_FREQ;
+  req.dev_id = devid;
+  req.min_freq_hz = freq_hz;
+  req.target_freq_hz = freq_hz;
+  req.max_freq_hz = freq_hz;
+  am62x_tisci_clkid(clkid, &clk_id, &clk_id_32);
+  req.clk_id = clk_id;
+  req.clk_id_32 = clk_id_32;
+
+  return am62x_tisci_xfer(&req.hdr, sizeof(req), &resp, sizeof(resp));
+}
+
+int am62x_tisci_get_clock_freq(uint32_t devid, uint32_t clkid,
+                               uint64_t *freq_hz)
+{
+  struct ti_sci_msg_req_get_clock_freq req;
+  struct ti_sci_msg_resp_get_clock_freq resp;
+  uint8_t clk_id;
+  uint32_t clk_id_32;
+  int ret;
+
+  memset(&req, 0, sizeof(req));
+  memset(&resp, 0, sizeof(resp));
+  req.hdr.type = TI_SCI_MSG_GET_CLOCK_FREQ;
+  req.dev_id = devid;
+  am62x_tisci_clkid(clkid, &clk_id, &clk_id_32);
+  req.clk_id = clk_id;
+  req.clk_id_32 = clk_id_32;
+
+  ret = am62x_tisci_xfer(&req.hdr, sizeof(req), &resp.hdr, sizeof(resp));
+  if (ret == OK && freq_hz != NULL)
+    {
+      *freq_hz = resp.freq_hz;
+    }
+
+  return ret;
+}
+
+int am62x_tisci_irq_set(uint16_t src_id, uint16_t src_index,
+                        uint16_t dst_id, uint16_t dst_host_irq)
+{
+  struct ti_sci_msg_req_manage_irq req;
+  struct ti_sci_msg_hdr resp;
+
+  memset(&req, 0, sizeof(req));
+  req.hdr.type = TI_SCI_MSG_RM_IRQ_SET;
+  req.valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
+  req.src_id = src_id;
+  req.src_index = src_index;
+  req.dst_id = dst_id;
+  req.dst_host_irq = dst_host_irq;
+
+  return am62x_tisci_xfer(&req.hdr, sizeof(req), &resp, sizeof(resp));
+}
+
+int am62x_tisci_irq_release(uint16_t src_id, uint16_t src_index,
+                            uint16_t dst_id, uint16_t dst_host_irq)
+{
+  struct ti_sci_msg_req_manage_irq req;
+  struct ti_sci_msg_hdr resp;
+
+  memset(&req, 0, sizeof(req));
+  req.hdr.type = TI_SCI_MSG_RM_IRQ_RELEASE;
+  req.valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
+  req.src_id = src_id;
+  req.src_index = src_index;
+  req.dst_id = dst_id;
+  req.dst_host_irq = dst_host_irq;
+
+  return am62x_tisci_xfer(&req.hdr, sizeof(req), &resp, sizeof(resp));
+}
+
+int am62x_tisci_initialize(void)
+{
+  struct am62x_tisci_version_s ver;
+  int ret;
+
+  ret = am62x_tisci_get_version(&ver);
+
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: TISCI version handshake failed: %d\n", ret);
+      return ret;
+    }
+
+  syslog(LOG_INFO,

Review Comment:
   Why call syslog here? Use the `nuttx/debug.h` macros instead.



##########
Documentation/platforms/arm64/am62x/boards/pocketbeagle2/index.rst:
##########
@@ -106,5 +110,8 @@ Configurations
 ``pocketbeagle2:nsh``
   Interactive NSH configuration for serial bring-up and shell access.
 
+``pocketbeagle2:i2c``

Review Comment:
   Ditto.



##########
arch/arm64/src/common/arm64_boot.c:
##########


Review Comment:
   This just clutters the diff, remove this.



##########
Documentation/platforms/arm64/am62x/boards/beagleplay/index.rst:
##########


Review Comment:
   Please align the formatting with the standard template: 
`Documentation/contributing/doc_templates/board.rst`



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to