LCOV - code coverage report
Current view: top level - zephyr/drivers - ipm.h Coverage Total Hit
Test: new.info Lines: 70.0 % 20 14
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /**
       2              :  * @file
       3              :  *
       4              :  * @brief Generic low-level inter-processor mailbox communication API.
       5              :  */
       6              : 
       7              : /*
       8              :  * Copyright (c) 2015 Intel Corporation
       9              :  *
      10              :  * SPDX-License-Identifier: Apache-2.0
      11              :  */
      12              : 
      13              : #ifndef ZEPHYR_INCLUDE_DRIVERS_IPM_H_
      14              : #define ZEPHYR_INCLUDE_DRIVERS_IPM_H_
      15              : 
      16              : /**
      17              :  * @brief IPM Interface
      18              :  * @defgroup ipm_interface IPM Interface
      19              :  * @since 1.0
      20              :  * @version 1.0.0
      21              :  * @ingroup io_interfaces
      22              :  * @{
      23              :  */
      24              : 
      25              : #include <zephyr/kernel.h>
      26              : #include <zephyr/device.h>
      27              : 
      28              : #ifdef __cplusplus
      29              : extern "C" {
      30              : #endif
      31              : 
      32              : /**
      33              :  * @typedef ipm_callback_t
      34              :  * @brief Callback API for incoming IPM messages
      35              :  *
      36              :  * These callbacks execute in interrupt context. Therefore, use only
      37              :  * interrupt-safe APIS. Registration of callbacks is done via
      38              :  * @a ipm_register_callback
      39              :  *
      40              :  * @param ipmdev Driver instance
      41              :  * @param user_data Pointer to some private data provided at registration
      42              :  *        time.
      43              :  * @param id Message type identifier.
      44              :  * @param data Message data pointer. The correct amount of data to read out
      45              :  *        must be inferred using the message id/upper level protocol.
      46              :  */
      47            1 : typedef void (*ipm_callback_t)(const struct device *ipmdev, void *user_data,
      48              :                                uint32_t id, volatile void *data);
      49              : 
      50              : /**
      51              :  * @typedef ipm_send_t
      52              :  * @brief Callback API to send IPM messages
      53              :  *
      54              :  * See @a ipm_send() for argument definitions.
      55              :  */
      56            1 : typedef int (*ipm_send_t)(const struct device *ipmdev, int wait, uint32_t id,
      57              :                           const void *data, int size);
      58              : /**
      59              :  * @typedef ipm_max_data_size_get_t
      60              :  * @brief Callback API to get maximum data size
      61              :  *
      62              :  * See @a ipm_max_data_size_get() for argument definitions.
      63              :  */
      64            1 : typedef int (*ipm_max_data_size_get_t)(const struct device *ipmdev);
      65              : 
      66              : /**
      67              :  * @typedef ipm_max_id_val_get_t
      68              :  * @brief Callback API to get the ID's maximum value
      69              :  *
      70              :  * See @a ipm_max_id_val_get() for argument definitions.
      71              :  */
      72            1 : typedef uint32_t (*ipm_max_id_val_get_t)(const struct device *ipmdev);
      73              : 
      74              : /**
      75              :  * @typedef ipm_register_callback_t
      76              :  * @brief Callback API upon registration
      77              :  *
      78              :  * See @a ipm_register_callback() for argument definitions.
      79              :  */
      80            1 : typedef void (*ipm_register_callback_t)(const struct device *port,
      81              :                                         ipm_callback_t cb,
      82              :                                         void *user_data);
      83              : 
      84              : /**
      85              :  * @typedef ipm_set_enabled_t
      86              :  * @brief Callback API upon enablement of interrupts
      87              :  *
      88              :  * See @a ipm_set_enabled() for argument definitions.
      89              :  */
      90            1 : typedef int (*ipm_set_enabled_t)(const struct device *ipmdev, int enable);
      91              : 
      92              : /**
      93              :  * @typedef ipm_complete_t
      94              :  * @brief Callback API upon command completion
      95              :  *
      96              :  * See @a ipm_complete() for argument definitions.
      97              :  */
      98            1 : typedef void (*ipm_complete_t)(const struct device *ipmdev);
      99              : 
     100            0 : __subsystem struct ipm_driver_api {
     101            0 :         ipm_send_t send;
     102            0 :         ipm_register_callback_t register_callback;
     103            0 :         ipm_max_data_size_get_t max_data_size_get;
     104            0 :         ipm_max_id_val_get_t max_id_val_get;
     105            0 :         ipm_set_enabled_t set_enabled;
     106              : #ifdef CONFIG_IPM_CALLBACK_ASYNC
     107              :         ipm_complete_t complete;
     108              : #endif
     109              : };
     110              : 
     111              : /**
     112              :  * @brief Try to send a message over the IPM device.
     113              :  *
     114              :  * A message is considered consumed once the remote interrupt handler
     115              :  * finishes. If there is deferred processing on the remote side,
     116              :  * or if outgoing messages must be queued and wait on an
     117              :  * event/semaphore, a high-level driver can implement that.
     118              :  *
     119              :  * There are constraints on how much data can be sent or the maximum value
     120              :  * of id. Use the @a ipm_max_data_size_get and @a ipm_max_id_val_get routines
     121              :  * to determine them.
     122              :  *
     123              :  * The @a size parameter is used only on the sending side to determine
     124              :  * the amount of data to put in the message registers. It is not passed along
     125              :  * to the receiving side. The upper-level protocol dictates the amount of
     126              :  * data read back.
     127              :  *
     128              :  * @param ipmdev Driver instance
     129              :  * @param wait If non-zero, busy-wait indefinitely for the remote to consume
     130              :  *             the message. The message is considered consumed
     131              :  *             once the remote interrupt handler finishes.
     132              :  *             If there is deferred processing on the remote side,
     133              :  *             or you would like to queue outgoing messages and wait on an
     134              :  *             event/semaphore, you can implement that in a high-level driver
     135              :  * @param id Message identifier. Values are constrained by
     136              :  *        @a ipm_max_data_size_get since many boards only allow for a
     137              :  *        subset of bits in a 32-bit register to store the ID.
     138              :  * @param data Pointer to the data sent in the message.
     139              :  * @param size Size of the data.
     140              :  *
     141              :  * @retval -EBUSY    If the remote hasn't yet read the last data sent.
     142              :  * @retval -EMSGSIZE If the supplied data size is unsupported by the driver.
     143              :  * @retval -EINVAL   If there was a bad parameter, such as: too-large id value.
     144              :  *                   or the device isn't an outbound IPM channel.
     145              :  * @retval 0         On success.
     146              :  */
     147            1 : __syscall int ipm_send(const struct device *ipmdev, int wait, uint32_t id,
     148              :                        const void *data, int size);
     149              : 
     150              : static inline int z_impl_ipm_send(const struct device *ipmdev, int wait,
     151              :                                   uint32_t id,
     152              :                                   const void *data, int size)
     153              : {
     154              :         const struct ipm_driver_api *api =
     155              :                 (const struct ipm_driver_api *)ipmdev->api;
     156              : 
     157              :         return api->send(ipmdev, wait, id, data, size);
     158              : }
     159              : 
     160              : /**
     161              :  * @brief Register a callback function for incoming messages.
     162              :  *
     163              :  * @param ipmdev Driver instance pointer.
     164              :  * @param cb Callback function to execute on incoming message interrupts.
     165              :  * @param user_data Application-specific data pointer which will be passed
     166              :  *        to the callback function when executed.
     167              :  */
     168            1 : static inline void ipm_register_callback(const struct device *ipmdev,
     169              :                                          ipm_callback_t cb, void *user_data)
     170              : {
     171              :         const struct ipm_driver_api *api =
     172              :                 (const struct ipm_driver_api *)ipmdev->api;
     173              : 
     174              :         api->register_callback(ipmdev, cb, user_data);
     175              : }
     176              : 
     177              : /**
     178              :  * @brief Return the maximum number of bytes possible in an outbound message.
     179              :  *
     180              :  * IPM implementations vary on the amount of data that can be sent in a
     181              :  * single message since the data payload is typically stored in registers.
     182              :  *
     183              :  * @param ipmdev Driver instance pointer.
     184              :  *
     185              :  * @return Maximum possible size of a message in bytes.
     186              :  */
     187            1 : __syscall int ipm_max_data_size_get(const struct device *ipmdev);
     188              : 
     189              : static inline int z_impl_ipm_max_data_size_get(const struct device *ipmdev)
     190              : {
     191              :         const struct ipm_driver_api *api =
     192              :                 (const struct ipm_driver_api *)ipmdev->api;
     193              : 
     194              :         return api->max_data_size_get(ipmdev);
     195              : }
     196              : 
     197              : 
     198              : /**
     199              :  * @brief Return the maximum id value possible in an outbound message.
     200              :  *
     201              :  * Many IPM implementations store the message's ID in a register with
     202              :  * some bits reserved for other uses.
     203              :  *
     204              :  * @param ipmdev Driver instance pointer.
     205              :  *
     206              :  * @return Maximum possible value of a message ID.
     207              :  */
     208            1 : __syscall uint32_t ipm_max_id_val_get(const struct device *ipmdev);
     209              : 
     210              : static inline uint32_t z_impl_ipm_max_id_val_get(const struct device *ipmdev)
     211              : {
     212              :         const struct ipm_driver_api *api =
     213              :                 (const struct ipm_driver_api *)ipmdev->api;
     214              : 
     215              :         return api->max_id_val_get(ipmdev);
     216              : }
     217              : 
     218              : /**
     219              :  * @brief Enable interrupts and callbacks for inbound channels.
     220              :  *
     221              :  * @param ipmdev Driver instance pointer.
     222              :  * @param enable Set to 0 to disable and to nonzero to enable.
     223              :  *
     224              :  * @retval 0       On success.
     225              :  * @retval -EINVAL If it isn't an inbound channel.
     226              :  */
     227            1 : __syscall int ipm_set_enabled(const struct device *ipmdev, int enable);
     228              : 
     229              : static inline int z_impl_ipm_set_enabled(const struct device *ipmdev,
     230              :                                          int enable)
     231              : {
     232              :         const struct ipm_driver_api *api =
     233              :                 (const struct ipm_driver_api *)ipmdev->api;
     234              : 
     235              :         return api->set_enabled(ipmdev, enable);
     236              : }
     237              : 
     238              : /**
     239              :  * @brief Signal asynchronous command completion
     240              :  *
     241              :  * Some IPM backends have an ability to deliver a command
     242              :  * asynchronously.  The callback will be invoked in interrupt context,
     243              :  * but the message (including the provided data pointer) will stay
     244              :  * "active" and unacknowledged until later code (presumably in thread
     245              :  * mode) calls ipm_complete().
     246              :  *
     247              :  * This function is, obviously, a noop on drivers without async
     248              :  * support.
     249              :  *
     250              :  * @param ipmdev Driver instance pointer.
     251              :  */
     252            1 : __syscall void ipm_complete(const struct device *ipmdev);
     253              : 
     254              : static inline void z_impl_ipm_complete(const struct device *ipmdev)
     255              : {
     256              : #ifdef CONFIG_IPM_CALLBACK_ASYNC
     257              :         const struct ipm_driver_api *api =
     258              :                 (const struct ipm_driver_api *)ipmdev->api;
     259              : 
     260              :         if (api->complete != NULL) {
     261              :                 api->complete(ipmdev);
     262              :         }
     263              : #endif
     264              : }
     265              : 
     266              : #ifdef __cplusplus
     267              : }
     268              : #endif
     269              : 
     270              : /**
     271              :  * @}
     272              :  */
     273              : 
     274              : #include <zephyr/syscalls/ipm.h>
     275              : 
     276              : #endif /* ZEPHYR_INCLUDE_DRIVERS_IPM_H_ */
        

Generated by: LCOV version 2.0-1