LCOV - code coverage report
Current view: top level - zephyr/drivers/firmware/scmi - transport.h Coverage Total Hit
Test: new.info Lines: 71.4 % 21 15
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /*
       2              :  * Copyright 2024 NXP
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @brief Public APIs for the SCMI transport layer drivers
      10              :  */
      11              : 
      12              : #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_TRANSPORT_H_
      13              : #define _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_TRANSPORT_H_
      14              : 
      15              : #include <zephyr/device.h>
      16              : #include <zephyr/kernel.h>
      17              : 
      18              : struct scmi_message;
      19              : struct scmi_channel;
      20              : 
      21              : /**
      22              :  * @typedef scmi_channel_cb
      23              :  *
      24              :  * @brief Callback function for message replies
      25              :  *
      26              :  * This function should be called by the transport layer
      27              :  * driver whenever a reply to a previously sent message
      28              :  * has been received. Its purpose is to notifying the SCMI
      29              :  * core of the reply's arrival so that proper action can
      30              :  * be taken.
      31              :  *
      32              :  * @param chan pointer to SCMI channel on which the reply
      33              :  * arrived
      34              :  */
      35            1 : typedef void (*scmi_channel_cb)(struct scmi_channel *chan);
      36              : 
      37              : /**
      38              :  * @struct scmi_channel
      39              :  * @brief SCMI channel structure
      40              :  *
      41              :  * An SCMI channel is a medium through which a protocol
      42              :  * is able to transmit/receive messages. Each of the SCMI
      43              :  * channels is represented by a `struct scmi_channel`.
      44              :  */
      45            1 : struct scmi_channel {
      46              :         /**
      47              :          * channel lock. This is meant to be initialized
      48              :          * and used only by the SCMI core to assure that
      49              :          * only one protocol can send/receive messages
      50              :          * through a channel at a given moment.
      51              :          */
      52            1 :         struct k_mutex lock;
      53              :         /**
      54              :          * binary semaphore. This is meant to be initialized
      55              :          * and used only by the SCMI core. Its purpose is to
      56              :          * signal that a reply has been received.
      57              :          */
      58            1 :         struct k_sem sem;
      59              :         /** channel private data */
      60            1 :         void *data;
      61              :         /**
      62              :          * callback function. This is meant to be set by
      63              :          * the SCMI core and should be called by the SCMI
      64              :          * transport layer driver whenever a reply has
      65              :          * been received.
      66              :          */
      67            1 :         scmi_channel_cb cb;
      68              :         /** is the channel ready to be used by a protocol? */
      69            1 :         bool ready;
      70              : };
      71              : 
      72            0 : struct scmi_transport_api {
      73            0 :         int (*init)(const struct device *transport);
      74            0 :         int (*send_message)(const struct device *transport,
      75              :                             struct scmi_channel *chan,
      76              :                             struct scmi_message *msg);
      77            0 :         int (*setup_chan)(const struct device *transport,
      78              :                           struct scmi_channel *chan,
      79              :                           bool tx);
      80            0 :         int (*read_message)(const struct device *transport,
      81              :                             struct scmi_channel *chan,
      82              :                             struct scmi_message *msg);
      83            0 :         bool (*channel_is_free)(const struct device *transport,
      84              :                                 struct scmi_channel *chan);
      85              :         struct scmi_channel *(*request_channel)(const struct device *transport,
      86              :                                                 uint32_t proto, bool tx);
      87              : };
      88              : 
      89              : /**
      90              :  * @brief Request an SCMI channel dynamically
      91              :  *
      92              :  * Whenever the SCMI transport layer driver doesn't support
      93              :  * static channel allocation, the SCMI core will try to bind
      94              :  * a channel to a protocol dynamically using this function.
      95              :  * Note that no setup needs to be performed on the channel
      96              :  * in this function as the core will also call the channel
      97              :  * setup() function.
      98              :  *
      99              :  * @param transport pointer to the device structure for the
     100              :  * transport layer
     101              :  * @param proto ID of the protocol for which the core is
     102              :  * requesting the channel
     103              :  * @param tx true if the channel is TX, false if RX
     104              :  *
     105              :  * @retval pointer to SCMI channel that's to be bound
     106              :  * to the protocol
     107              :  * @retval NULL if operation was not successful
     108              :  */
     109              : static inline struct scmi_channel *
     110            1 : scmi_transport_request_channel(const struct device *transport,
     111              :                                uint32_t proto, bool tx)
     112              : {
     113              :         const struct scmi_transport_api *api =
     114              :                 (const struct scmi_transport_api *)transport->api;
     115              : 
     116              :         if (api->request_channel) {
     117              :                 return api->request_channel(transport, proto, tx);
     118              :         }
     119              : 
     120              :         return NULL;
     121              : }
     122              : 
     123              : /**
     124              :  * @brief Perform initialization for the transport layer driver
     125              :  *
     126              :  * The transport layer driver can't be initialized directly
     127              :  * (i.e via a call to its init() function) during system initialization.
     128              :  * This is because the macro used to define an SCMI transport places
     129              :  * `scmi_core_transport_init()` in the init section instead of the
     130              :  * driver's init() function. As such, `scmi_core_transport_init()`
     131              :  * needs to call this function to perfrom transport layer driver
     132              :  * initialization if required.
     133              :  *
     134              :  * This operation is optional.
     135              :  *
     136              :  * @param transport pointer to the device structure for the
     137              :  * transport layer
     138              :  *
     139              :  * @retval 0 if successful
     140              :  * @retval negative errno code if failure
     141              :  */
     142            1 : static inline int scmi_transport_init(const struct device *transport)
     143              : {
     144              :         const struct scmi_transport_api *api =
     145              :                 (const struct scmi_transport_api *)transport->api;
     146              : 
     147              :         if (api->init) {
     148              :                 return api->init(transport);
     149              :         }
     150              : 
     151              :         return 0;
     152              : }
     153              : 
     154              : /**
     155              :  * @brief Setup an SCMI channel
     156              :  *
     157              :  * Before being able to send/receive messages, an SCMI channel needs
     158              :  * to be prepared, which is what this function does. If it returns
     159              :  * successfully, an SCMI protocol will be able to use this channel
     160              :  * to send/receive messages.
     161              :  *
     162              :  * @param transport pointer to the device structure for the
     163              :  * transport layer
     164              :  * @param chan pointer to SCMI channel to be prepared
     165              :  * @param tx true if the channel is TX, false if RX
     166              :  *
     167              :  * @retval 0 if successful
     168              :  * @retval negative errno code if failure
     169              :  */
     170            1 : static inline int scmi_transport_setup_chan(const struct device *transport,
     171              :                                             struct scmi_channel *chan,
     172              :                                             bool tx)
     173              : {
     174              :         const struct scmi_transport_api *api =
     175              :                 (const struct scmi_transport_api *)transport->api;
     176              : 
     177              :         if (!api || !api->setup_chan) {
     178              :                 return -ENOSYS;
     179              :         }
     180              : 
     181              :         return api->setup_chan(transport, chan, tx);
     182              : }
     183              : 
     184              : /**
     185              :  * @brief Send an SCMI channel
     186              :  *
     187              :  * Send an SCMI message using given SCMI channel. This function is
     188              :  * not allowed to block.
     189              :  *
     190              :  * @param transport pointer to the device structure for the
     191              :  * transport layer
     192              :  * @param chan pointer to SCMI channel on which the message
     193              :  * is to be sent
     194              :  * @param msg pointer to message the caller wishes to send
     195              :  *
     196              :  * @retval 0 if successful
     197              :  * @retval negative errno code if failure
     198              :  */
     199            1 : static inline int scmi_transport_send_message(const struct device *transport,
     200              :                                               struct scmi_channel *chan,
     201              :                                               struct scmi_message *msg)
     202              : {
     203              :         const struct scmi_transport_api *api =
     204              :                 (const struct scmi_transport_api *)transport->api;
     205              : 
     206              :         if (!api || !api->send_message) {
     207              :                 return -ENOSYS;
     208              :         }
     209              : 
     210              :         return api->send_message(transport, chan, msg);
     211              : }
     212              : 
     213              : /**
     214              :  * @brief Read an SCMI message
     215              :  *
     216              :  * @param transport pointer to the device structure for the
     217              :  * transport layer
     218              :  * @param chan pointer to SCMI channel on which the message
     219              :  * is to be read
     220              :  * @param msg pointer to message the caller wishes to read
     221              :  *
     222              :  * @retval 0 if successful
     223              :  * @retval negative errno code if failure
     224              :  */
     225            1 : static inline int scmi_transport_read_message(const struct device *transport,
     226              :                                               struct scmi_channel *chan,
     227              :                                               struct scmi_message *msg)
     228              : {
     229              :         const struct scmi_transport_api *api =
     230              :                 (const struct scmi_transport_api *)transport->api;
     231              : 
     232              :         if (!api || !api->read_message) {
     233              :                 return -ENOSYS;
     234              :         }
     235              : 
     236              :         return api->read_message(transport, chan, msg);
     237              : }
     238              : 
     239              : /**
     240              :  * @brief Check if an SCMI channel is free
     241              :  *
     242              :  * @param transport pointer to the device structure for
     243              :  * the transport layer
     244              :  * @param chan pointer to SCMI channel the query is to be
     245              :  * performed on
     246              :  *
     247              :  * @retval 0 if successful
     248              :  * @retval negative errno code if failure
     249              :  */
     250            1 : static inline bool scmi_transport_channel_is_free(const struct device *transport,
     251              :                                                   struct scmi_channel *chan)
     252              : {
     253              :         const struct scmi_transport_api *api =
     254              :                 (const struct scmi_transport_api *)transport->api;
     255              : 
     256              :         if (!api || !api->channel_is_free) {
     257              :                 return -ENOSYS;
     258              :         }
     259              : 
     260              :         return api->channel_is_free(transport, chan);
     261              : }
     262              : 
     263              : /**
     264              :  * @brief Perfrom SCMI core initialization
     265              :  *
     266              :  * @param transport pointer to the device structure for
     267              :  * the transport layer
     268              :  *
     269              :  * @retval 0 if successful
     270              :  * @retval negative errno code if failure
     271              :  */
     272            1 : int scmi_core_transport_init(const struct device *transport);
     273              : 
     274              : #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_TRANSPORT_H_ */
        

Generated by: LCOV version 2.0-1