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
@@ -143,6 +150,19 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
143150 uint32_t dst , const void * data , int len ,
144151 int wait );
145152
153+ /**
154+ * is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
155+ *
156+ * @ept: pointer to rpmsg endpoint
157+ *
158+ * Returns 1 if the rpmsg endpoint has both local addr and destination
159+ * addr set, 0 otherwise
160+ */
161+ static inline unsigned int is_rpmsg_ept_ready (struct rpmsg_endpoint * ept )
162+ {
163+ return ept && ept -> rdev && ept -> dest_addr != RPMSG_ADDR_ANY ;
164+ }
165+
146166/**
147167 * rpmsg_send() - send a message across to the remote processor
148168 * @ept: the rpmsg endpoint
@@ -161,8 +181,17 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
161181static inline int rpmsg_send (struct rpmsg_endpoint * ept , const void * data ,
162182 int len )
163183{
164- return rpmsg_send_offchannel_raw (ept , ept -> addr , ept -> dest_addr , data ,
165- len , true);
184+ int tc = 0 ;
185+
186+ for (; tc < RPMSG_TICK_COUNT ; tc += RPMSG_TICKS_PER_INTERVAL ) {
187+ if (is_rpmsg_ept_ready (ept ))
188+ return rpmsg_send_offchannel_raw (ept , ept -> addr ,
189+ ept -> dest_addr ,
190+ data , len , true);
191+ metal_sleep_usec (RPMSG_TICKS_PER_INTERVAL );
192+ }
193+
194+ return RPMSG_ERR_ADDR ;
166195}
167196
168197/**
@@ -435,8 +464,17 @@ static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept,
435464static inline int rpmsg_send_nocopy (struct rpmsg_endpoint * ept ,
436465 const void * data , int len )
437466{
438- return rpmsg_send_offchannel_nocopy (ept , ept -> addr ,
439- ept -> dest_addr , data , len );
467+ int tc = 0 ;
468+
469+ for (; tc < RPMSG_TICK_COUNT ; tc += RPMSG_TICKS_PER_INTERVAL ) {
470+ if (is_rpmsg_ept_ready (ept ))
471+ return rpmsg_send_offchannel_nocopy (ept , ept -> addr ,
472+ ept -> dest_addr ,
473+ data , len );
474+ metal_sleep_usec (RPMSG_TICKS_PER_INTERVAL );
475+ }
476+
477+ return RPMSG_ERR_ADDR ;
440478}
441479
442480/**
@@ -480,19 +518,6 @@ int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
480518 */
481519void rpmsg_destroy_ept (struct rpmsg_endpoint * ept );
482520
483- /**
484- * is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
485- *
486- * @ept: pointer to rpmsg endpoint
487- *
488- * Returns 1 if the rpmsg endpoint has both local addr and destination
489- * addr set, 0 otherwise
490- */
491- static inline unsigned int is_rpmsg_ept_ready (struct rpmsg_endpoint * ept )
492- {
493- return ept && ept -> rdev && ept -> dest_addr != RPMSG_ADDR_ANY ;
494- }
495-
496521#if defined __cplusplus
497522 }
498523#endif
0 commit comments