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
@@ -179,6 +186,19 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
179186 uint32_t dst , const void * data , int len ,
180187 int wait );
181188
189+ /**
190+ * @brief Check if the rpmsg endpoint ready to send
191+ *
192+ * @ept: pointer to rpmsg endpoint
193+ *
194+ * Returns 1 if the rpmsg endpoint has both local addr and destination
195+ * addr set, 0 otherwise
196+ */
197+ static inline unsigned int is_rpmsg_ept_ready (struct rpmsg_endpoint * ept )
198+ {
199+ return ept && ept -> rdev && ept -> dest_addr != RPMSG_ADDR_ANY ;
200+ }
201+
182202/**
183203 * @brief Send a message across to the remote processor
184204 *
@@ -198,11 +218,20 @@ int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
198218static inline int rpmsg_send (struct rpmsg_endpoint * ept , const void * data ,
199219 int len )
200220{
221+ int tc = 0 ;
222+
201223 if (!ept )
202224 return RPMSG_ERR_PARAM ;
203225
204- return rpmsg_send_offchannel_raw (ept , ept -> addr , ept -> dest_addr , data ,
205- len , true);
226+ for (; tc < RPMSG_TICK_COUNT ; tc += RPMSG_TICKS_PER_INTERVAL ) {
227+ if (is_rpmsg_ept_ready (ept ))
228+ return rpmsg_send_offchannel_raw (ept , ept -> addr ,
229+ ept -> dest_addr ,
230+ data , len , true);
231+ metal_sleep_usec (RPMSG_TICKS_PER_INTERVAL );
232+ }
233+
234+ return RPMSG_ERR_ADDR ;
206235}
207236
208237/**
@@ -538,11 +567,20 @@ static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept,
538567static inline int rpmsg_send_nocopy (struct rpmsg_endpoint * ept ,
539568 const void * data , int len )
540569{
570+ int tc = 0 ;
571+
541572 if (!ept )
542573 return RPMSG_ERR_PARAM ;
543574
544- return rpmsg_send_offchannel_nocopy (ept , ept -> addr ,
545- ept -> dest_addr , data , len );
575+ for (; tc < RPMSG_TICK_COUNT ; tc += RPMSG_TICKS_PER_INTERVAL ) {
576+ if (is_rpmsg_ept_ready (ept ))
577+ return rpmsg_send_offchannel_nocopy (ept , ept -> addr ,
578+ ept -> dest_addr ,
579+ data , len );
580+ metal_sleep_usec (RPMSG_TICKS_PER_INTERVAL );
581+ }
582+
583+ return RPMSG_ERR_ADDR ;
546584}
547585
548586/**
@@ -587,19 +625,6 @@ int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
587625 */
588626void rpmsg_destroy_ept (struct rpmsg_endpoint * ept );
589627
590- /**
591- * @brief Check if the rpmsg endpoint ready to send
592- *
593- * @param ept Pointer to rpmsg endpoint
594- *
595- * @return 1 if the rpmsg endpoint has both local addr and destination
596- * addr set, 0 otherwise
597- */
598- static inline unsigned int is_rpmsg_ept_ready (struct rpmsg_endpoint * ept )
599- {
600- return ept && ept -> rdev && ept -> dest_addr != RPMSG_ADDR_ANY ;
601- }
602-
603628#if defined __cplusplus
604629 }
605630#endif
0 commit comments