5555#define trace_idc_error (__e ) trace_error(TRACE_CLASS_IDC, __e)
5656
5757
58+ /** \brief IDC send blocking flag. */
59+ #define IDC_BLOCKING 0
60+
61+ /** \brief IDC send non-blocking flag. */
62+ #define IDC_NON_BLOCKING 1
63+
64+ /** \brief IDC send timeout in cycles. */
65+ #define IDC_TIMEOUT 800000
66+
5867/** \brief ROM wake version parsed by ROM during core wake up. */
5968#define IDC_ROM_WAKE_VERSION 0x2
6069
@@ -165,11 +174,16 @@ static void idc_irq_handler(void *arg)
165174/**
166175 * \brief Sends IDC message.
167176 * \param[in,out] msg Pointer to IDC message.
177+ * \param[in] mode Is message blocking or not.
178+ * \return Error code.
168179 */
169- static inline void arch_idc_send_msg (struct idc_msg * msg )
180+ static inline int arch_idc_send_msg (struct idc_msg * msg , uint32_t mode )
170181{
171182 struct idc * idc = * idc_get ();
172183 int core = arch_cpu_get_id ();
184+ int ret = 0 ;
185+ uint32_t timeout = 0 ;
186+ uint32_t idcietc ;
173187 uint32_t flags ;
174188
175189 tracev_idc ("Msg" );
@@ -179,7 +193,23 @@ static inline void arch_idc_send_msg(struct idc_msg *msg)
179193 idc_write (IPC_IDCIETC (msg -> core ), core , msg -> extension );
180194 idc_write (IPC_IDCITC (msg -> core ), core , msg -> header | IPC_IDCITC_BUSY );
181195
196+ if (mode == IDC_BLOCKING ) {
197+ do {
198+ idelay (PLATFORM_DEFAULT_DELAY );
199+ timeout += PLATFORM_DEFAULT_DELAY ;
200+ idcietc = idc_read (IPC_IDCIETC (msg -> core ), core );
201+ } while (!(idcietc & IPC_IDCIETC_DONE ) &&
202+ timeout < IDC_TIMEOUT );
203+
204+ if (timeout >= IDC_TIMEOUT ) {
205+ trace_idc_error ("eS0" );
206+ ret = - ETIME ;
207+ }
208+ }
209+
182210 spin_unlock_irq (& idc -> lock , flags );
211+
212+ return ret ;
183213}
184214
185215/**
0 commit comments