1515#include <metal/compiler.h>
1616#include <metal/mutex.h>
1717#include <metal/list.h>
18+ #include <metal/sleep.h>
1819#include <metal/utilities.h>
1920#include <string.h>
2021#include <stdbool.h>
@@ -32,6 +33,12 @@ extern "C" {
3233#define RPMSG_RESERVED_ADDRESSES (1024)
3334#define RPMSG_ADDR_ANY 0xFFFFFFFF
3435
36+ /* Total tick count for 15secs - 1usec tick. */
37+ #define RPMSG_TICK_COUNT 15000000
38+
39+ /* Time to wait - In multiple of 1 msecs. */
40+ #define RPMSG_TICKS_PER_INTERVAL 1000
41+
3542/* Error macros. */
3643#define RPMSG_SUCCESS 0
3744#define RPMSG_ERROR_BASE -2000
@@ -173,6 +180,19 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
173180 uint32_t dst , const void * data , int len ,
174181 int wait );
175182
183+ /**
184+ * is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
185+ *
186+ * @ept: pointer to rpmsg endpoint
187+ *
188+ * Returns 1 if the rpmsg endpoint has both local addr and destination
189+ * addr set, 0 otherwise
190+ */
191+ static inline unsigned int is_rpmsg_ept_ready (struct rpmsg_endpoint * ept )
192+ {
193+ return ept && ept -> rdev && ept -> dest_addr != RPMSG_ADDR_ANY ;
194+ }
195+
176196/**
177197 * @brief Send a message across to the remote processor
178198 *
@@ -192,11 +212,20 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
192212static inline int rpmsg_send (struct rpmsg_endpoint * ept , const void * data ,
193213 int len )
194214{
215+ int tc = 0 ;
216+
195217 if (!ept )
196218 return RPMSG_ERR_PARAM ;
197219
198- return rpmsg_send_offchannel_raw (ept , ept -> addr , ept -> dest_addr , data ,
199- len , true);
220+ for (; tc < RPMSG_TICK_COUNT ; tc += RPMSG_TICKS_PER_INTERVAL ) {
221+ if (is_rpmsg_ept_ready (ept ))
222+ return rpmsg_send_offchannel_raw (ept , ept -> addr ,
223+ ept -> dest_addr ,
224+ data , len , true);
225+ metal_sleep_usec (RPMSG_TICKS_PER_INTERVAL );
226+ }
227+
228+ return RPMSG_ERR_ADDR ;
200229}
201230
202231/**
@@ -508,11 +537,20 @@ static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept,
508537static inline int rpmsg_send_nocopy (struct rpmsg_endpoint * ept ,
509538 const void * data , int len )
510539{
540+ int tc = 0 ;
541+
511542 if (!ept )
512543 return RPMSG_ERR_PARAM ;
513544
514- return rpmsg_send_offchannel_nocopy (ept , ept -> addr ,
515- ept -> dest_addr , data , len );
545+ for (; tc < RPMSG_TICK_COUNT ; tc += RPMSG_TICKS_PER_INTERVAL ) {
546+ if (is_rpmsg_ept_ready (ept ))
547+ return rpmsg_send_offchannel_nocopy (ept , ept -> addr ,
548+ ept -> dest_addr ,
549+ data , len );
550+ metal_sleep_usec (RPMSG_TICKS_PER_INTERVAL );
551+ }
552+
553+ return RPMSG_ERR_ADDR ;
516554}
517555
518556/**
@@ -557,19 +595,6 @@ int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
557595 */
558596void rpmsg_destroy_ept (struct rpmsg_endpoint * ept );
559597
560- /**
561- * @brief Check if the rpmsg endpoint ready to send
562- *
563- * @param ept Pointer to rpmsg endpoint
564- *
565- * @return 1 if the rpmsg endpoint has both local addr and destination
566- * addr set, 0 otherwise
567- */
568- static inline unsigned int is_rpmsg_ept_ready (struct rpmsg_endpoint * ept )
569- {
570- return ept && ept -> rdev && ept -> dest_addr != RPMSG_ADDR_ANY ;
571- }
572-
573598#if defined __cplusplus
574599 }
575600#endif
0 commit comments