1 /******************************************************************************
2 *
3 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4 * Analog Devices, Inc.),
5 * Copyright (C) 2023-2024 Analog Devices, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************************/
20
21 #include <string.h>
22 #include <stdlib.h>
23 #include "mxc_device.h"
24 #include "mxc_errors.h"
25 #include "mxc_assert.h"
26 #include "mxc_sys.h"
27 #include "sema_reva.h"
28
29 /* Semaphores used for each mailbox */
30 #ifndef SEMA_BOX0_SEMA
31 #define SEMA_BOX0_SEMA (MXC_CFG_SEMA_INSTANCES - 2)
32 #endif
33
34 #ifndef SEMA_BOX1_SEMA
35 #define SEMA_BOX1_SEMA (MXC_CFG_SEMA_INSTANCES - 1)
36 #endif
37
38 #ifndef MAILBOX_SIZE
39 #define MAILBOX_SIZE 0
40 #elif ((MAILBOX_SIZE != 0) && (MAILBOX_SIZE < 16))
41 #error Mailbox size must be at least 16
42 #endif
43
44 /* Size of the payload in the mailbox */
45 #define MAILBOX_OVERHEAD (2 * sizeof(uint16_t))
46 #define MAILBOX_PAYLOAD_LEN (MAILBOX_SIZE - MAILBOX_OVERHEAD)
47
48 #ifdef __riscv
49 /* RISCV reads from mailbox 0 and writes to mailbox 1 */
50 #define SEMA_READ_BOX 0
51 #define SEMA_WRITE_BOX 1
52 #define SEMA_READ_SEMA SEMA_BOX0_SEMA
53 #define SEMA_WRITE_SEMA SEMA_BOX1_SEMA
54 #else
55 /* ARM reads from mailbox 1 and writes to mailbox 0 */
56 #define SEMA_READ_BOX 1
57 #define SEMA_WRITE_BOX 0
58 #define SEMA_READ_SEMA SEMA_BOX1_SEMA
59 #define SEMA_WRITE_SEMA SEMA_BOX0_SEMA
60 #endif
61
62 /*
63 Pointers to the mailbox locations in memory, ARM and RISCV must have matching
64 views of the mailboxes.
65 */
66 extern uint32_t _mailbox_0;
67 extern uint32_t _mailbox_1;
68
69 /*
70 Mailbox Control block.
71
72 Write location indicates where the next write will start.
73 Read location indicates where next read will start.
74 write pointer == read pointer indicate empty buffer
75 */
76 typedef struct {
77 uint16_t readLocation;
78 uint16_t writeLocation;
79 #if (MAILBOX_SIZE == 0)
80 uint8_t payload[1];
81 #else
82 uint8_t payload[MAILBOX_SIZE - MAILBOX_OVERHEAD];
83 #endif
84 } mxcSemaBox_t;
85 mxcSemaBox_t *mxcSemaBox0 = (mxcSemaBox_t *)&_mailbox_0;
86 mxcSemaBox_t *mxcSemaBox1 = (mxcSemaBox_t *)&_mailbox_1;
87
88 /* Semaphore control block. */
89 typedef struct {
90 uint8_t *readBuf;
91 unsigned readLen;
92 mxc_sema_complete_cb_t readCb;
93
94 uint8_t *writeBuf;
95 unsigned writeLen;
96 mxc_sema_complete_cb_t writeCb;
97 } mxcSemaCb_t;
98 mxcSemaCb_t mxcSemaCb;
99
MXC_SEMA_RevA_GetSema(mxc_sema_reva_regs_t * sema_regs,unsigned sema)100 int MXC_SEMA_RevA_GetSema(mxc_sema_reva_regs_t *sema_regs, unsigned sema)
101 {
102 uint32_t sema_val;
103 MXC_ASSERT(sema < MXC_CFG_SEMA_INSTANCES);
104
105 // Reading the register does an atomic test and set, returns previous value
106 sema_val = sema_regs->semaphores[sema];
107
108 if (sema_val == 0) {
109 return E_NO_ERROR;
110 } else {
111 return E_BUSY;
112 }
113 }
114
MXC_SEMA_RevA_CheckSema(mxc_sema_reva_regs_t * sema_regs,unsigned sema)115 int MXC_SEMA_RevA_CheckSema(mxc_sema_reva_regs_t *sema_regs, unsigned sema)
116 {
117 MXC_ASSERT(sema < MXC_CFG_SEMA_INSTANCES);
118
119 if (sema_regs->status & (0x1 << sema)) {
120 return E_BUSY;
121 } else {
122 return E_NO_ERROR;
123 }
124 }
125
MXC_SEMA_RevA_Status(mxc_sema_reva_regs_t * sema_regs)126 uint32_t MXC_SEMA_RevA_Status(mxc_sema_reva_regs_t *sema_regs)
127 {
128 return sema_regs->status;
129 }
130
MXC_SEMA_RevA_FreeSema(mxc_sema_reva_regs_t * sema_regs,unsigned sema)131 void MXC_SEMA_RevA_FreeSema(mxc_sema_reva_regs_t *sema_regs, unsigned sema)
132 {
133 MXC_ASSERT(sema < MXC_CFG_SEMA_INSTANCES);
134
135 sema_regs->semaphores[sema] = 0x0;
136 }
137
MXC_SEMA_RevA_Init(mxc_sema_reva_regs_t * sema_regs)138 int MXC_SEMA_RevA_Init(mxc_sema_reva_regs_t *sema_regs)
139 {
140 if (MAILBOX_SIZE == 0) {
141 return E_NONE_AVAIL;
142 } else {
143 /* Reset the async state */
144 mxcSemaCb.readBuf = NULL;
145 mxcSemaCb.readLen = 0;
146 mxcSemaCb.writeBuf = NULL;
147 mxcSemaCb.writeLen = 0;
148
149 /* Enable the semaphore interrupt */
150 #ifndef __riscv
151 sema_regs->irq0 |= MXC_F_SEMA_REVA_IRQ0_EN;
152 #else
153 sema_regs->irq1 |= MXC_F_SEMA_REVA_IRQ1_EN;
154 #endif
155
156 return E_NO_ERROR;
157 }
158 }
159
MXC_SEMA_RevA_InitBoxes(mxc_sema_reva_regs_t * sema_regs)160 int MXC_SEMA_RevA_InitBoxes(mxc_sema_reva_regs_t *sema_regs)
161 {
162 if (MAILBOX_SIZE == 0) {
163 return E_NONE_AVAIL;
164 } else {
165 /* Reset the boxes */
166 memset((void *)mxcSemaBox0, 0, MAILBOX_SIZE);
167 memset((void *)mxcSemaBox1, 0, MAILBOX_SIZE);
168
169 return E_NO_ERROR;
170 }
171 }
172
semaGetReadBoxAvailLen(void)173 static unsigned semaGetReadBoxAvailLen(void)
174 {
175 unsigned length;
176 int diff;
177
178 if (SEMA_READ_BOX == 1) {
179 diff = mxcSemaBox1->writeLocation - mxcSemaBox1->readLocation;
180 } else {
181 diff = mxcSemaBox0->writeLocation - mxcSemaBox0->readLocation;
182 }
183
184 /* Wrap if write pointer is behind the read pointer */
185 if (diff < 0) {
186 length = MAILBOX_PAYLOAD_LEN + diff;
187 } else {
188 length = diff;
189 }
190
191 return length;
192 }
193
semaReadBox(mxc_sema_reva_regs_t * sema_regs,mxcSemaBox_t * box,uint8_t * data,uint16_t len)194 static void semaReadBox(mxc_sema_reva_regs_t *sema_regs, mxcSemaBox_t *box, uint8_t *data,
195 uint16_t len)
196 {
197 /* Copy data from the box to the buffer */
198 memcpy(data, &box->payload[box->readLocation], len);
199
200 /* Advance and wrap the pointers */
201 box->readLocation += len;
202 box->readLocation = box->readLocation % MAILBOX_PAYLOAD_LEN;
203 }
204
MXC_SEMA_RevA_ReadBox(mxc_sema_reva_regs_t * sema_regs,uint8_t * data,unsigned len)205 int MXC_SEMA_RevA_ReadBox(mxc_sema_reva_regs_t *sema_regs, uint8_t *data, unsigned len)
206 {
207 int err;
208 unsigned readLen;
209 mxcSemaBox_t *readBox;
210
211 if (MAILBOX_SIZE == 0) {
212 return E_NONE_AVAIL;
213 } else {
214 /* Lock the semaphore */
215 err = MXC_SEMA_RevA_GetSema(sema_regs, SEMA_READ_SEMA);
216 if (err != E_NO_ERROR) {
217 return E_BUSY;
218 }
219
220 /* Get the available read length */
221 if (len > semaGetReadBoxAvailLen()) {
222 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_READ_SEMA);
223 return E_UNDERFLOW;
224 }
225
226 /* Assign the box pointer */
227 if (SEMA_READ_BOX == 1) {
228 readBox = mxcSemaBox1;
229 } else if (SEMA_READ_BOX == 0) {
230 readBox = mxcSemaBox0;
231 }
232
233 /* Portion the read */
234 if (readBox->writeLocation < readBox->readLocation) {
235 /* Write location is behind the read location, wrap at the boundary */
236 if (len > (MAILBOX_PAYLOAD_LEN - readBox->readLocation)) {
237 readLen = (MAILBOX_PAYLOAD_LEN - readBox->readLocation);
238 semaReadBox(sema_regs, readBox, data, readLen);
239 data += readLen;
240 len -= readLen;
241 }
242 }
243
244 /* Complete the read */
245 semaReadBox(sema_regs, readBox, data, len);
246
247 /* Release the semaphore */
248 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_READ_SEMA);
249
250 /* Interrupt the peer when we're done reading */
251 #if TARGET_NUM == 32570 || TARGET_NUM == 32650 || TARGET_NUM == 32665
252 #ifndef __riscv
253 sema_regs->irq1 |= MXC_F_SEMA_REVA_IRQ1_RV32_IRQ;
254 #else
255 sema_regs->irq0 |= MXC_F_SEMA_REVA_IRQ0_CM4_IRQ;
256 #endif
257 #else
258 #ifndef __riscv
259 sema_regs->irq1 |= MXC_F_SEMA_IRQ1_RV32_IRQ;
260 #else
261 sema_regs->irq0 |= MXC_F_SEMA_IRQ0_CM4_IRQ;
262 #endif
263 #endif
264
265 return E_NO_ERROR;
266 }
267 }
268
MXC_SEMA_RevA_ReadBoxAsync(mxc_sema_reva_regs_t * sema_regs,mxc_sema_complete_cb_t cb,uint8_t * data,unsigned len)269 int MXC_SEMA_RevA_ReadBoxAsync(mxc_sema_reva_regs_t *sema_regs, mxc_sema_complete_cb_t cb,
270 uint8_t *data, unsigned len)
271 {
272 if (MAILBOX_SIZE == 0) {
273 return E_NONE_AVAIL;
274 } else {
275 /* Read currently in progress */
276 if (mxcSemaCb.readBuf != NULL) {
277 return E_BUSY;
278 }
279
280 /* Register the read request */
281 mxcSemaCb.readBuf = data;
282 mxcSemaCb.readLen = len;
283 mxcSemaCb.readCb = cb;
284
285 /* Pend the local interrupt to process the request */
286 #if TARGET_NUM == 32570 || TARGET_NUM == 32650 || TARGET_NUM == 32665
287 #ifdef __riscv
288 sema_regs->irq1 |= MXC_F_SEMA_REVA_IRQ1_RV32_IRQ;
289 #else
290 sema_regs->irq0 |= MXC_F_SEMA_REVA_IRQ0_CM4_IRQ;
291 #endif
292 #else
293 #ifdef __riscv
294 sema_regs->irq1 |= MXC_F_SEMA_IRQ1_RV32_IRQ;
295 #else
296 sema_regs->irq0 |= MXC_F_SEMA_IRQ0_CM4_IRQ;
297 #endif
298 #endif
299
300 return E_NO_ERROR;
301 }
302 }
303
semaGetWriteBoxAvailLen(void)304 static unsigned semaGetWriteBoxAvailLen(void)
305 {
306 unsigned length;
307 int diff;
308
309 if (SEMA_WRITE_BOX == 1) {
310 diff = mxcSemaBox1->readLocation - mxcSemaBox1->writeLocation;
311 } else {
312 diff = mxcSemaBox0->readLocation - mxcSemaBox0->writeLocation;
313 }
314
315 /* Wrap if read pointer is behind the write pointer */
316 if (diff == 0) {
317 length = MAILBOX_PAYLOAD_LEN - 1;
318 } else if (diff < 0) {
319 length = MAILBOX_PAYLOAD_LEN + diff - 1;
320 } else {
321 length = diff - 1;
322 }
323
324 return length;
325 }
326
semaWriteBox(mxc_sema_reva_regs_t * sema_regs,mxcSemaBox_t * box,const uint8_t * data,unsigned len)327 static void semaWriteBox(mxc_sema_reva_regs_t *sema_regs, mxcSemaBox_t *box, const uint8_t *data,
328 unsigned len)
329 {
330 /* Copy data from the buffer to the box */
331 memcpy(&box->payload[box->writeLocation], data, len);
332 box->writeLocation += len;
333 box->writeLocation = box->writeLocation % MAILBOX_PAYLOAD_LEN;
334 }
335
MXC_SEMA_RevA_WriteBox(mxc_sema_reva_regs_t * sema_regs,const uint8_t * data,unsigned len)336 int MXC_SEMA_RevA_WriteBox(mxc_sema_reva_regs_t *sema_regs, const uint8_t *data, unsigned len)
337 {
338 mxcSemaBox_t *writeBox;
339 unsigned writeLen;
340 int err;
341
342 if (MAILBOX_SIZE == 0) {
343 return E_NONE_AVAIL;
344 } else {
345 err = MXC_SEMA_RevA_GetSema(sema_regs, SEMA_WRITE_SEMA);
346 if (err != E_NO_ERROR) {
347 return E_BUSY;
348 }
349
350 if (len > semaGetWriteBoxAvailLen()) {
351 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_WRITE_SEMA);
352 return E_OVERFLOW;
353 }
354
355 if (SEMA_WRITE_BOX == 1) {
356 writeBox = mxcSemaBox1;
357 } else if (SEMA_WRITE_BOX == 0) {
358 writeBox = mxcSemaBox0;
359 }
360
361 /* Portion the write */
362 if (len > (MAILBOX_PAYLOAD_LEN - writeBox->writeLocation)) {
363 writeLen = (MAILBOX_PAYLOAD_LEN - writeBox->writeLocation);
364 semaWriteBox(sema_regs, writeBox, data, writeLen);
365 data += writeLen;
366 len -= writeLen;
367 }
368
369 /* Complete the write */
370 semaWriteBox(sema_regs, writeBox, data, len);
371
372 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_WRITE_SEMA);
373
374 /* Interrupt the peer when we're done writing */
375 #if TARGET_NUM == 32570 || TARGET_NUM == 32650 || TARGET_NUM == 32665
376 #ifndef __riscv
377 sema_regs->irq1 |= MXC_F_SEMA_REVA_IRQ1_RV32_IRQ;
378 #else
379 sema_regs->irq0 |= MXC_F_SEMA_REVA_IRQ0_CM4_IRQ;
380 #endif
381 #else
382 #ifndef __riscv
383 sema_regs->irq1 |= MXC_F_SEMA_IRQ1_RV32_IRQ;
384 #else
385 sema_regs->irq0 |= MXC_F_SEMA_IRQ0_CM4_IRQ;
386 #endif
387 #endif
388
389 return E_NO_ERROR;
390 }
391 }
392
MXC_SEMA_RevA_WriteBoxAsync(mxc_sema_reva_regs_t * sema_regs,mxc_sema_complete_cb_t cb,const uint8_t * data,unsigned len)393 int MXC_SEMA_RevA_WriteBoxAsync(mxc_sema_reva_regs_t *sema_regs, mxc_sema_complete_cb_t cb,
394 const uint8_t *data, unsigned len)
395 {
396 if (MAILBOX_SIZE == 0) {
397 return E_NONE_AVAIL;
398 } else {
399 /* Read currently in progress */
400 if (mxcSemaCb.writeBuf != NULL) {
401 return E_BUSY;
402 }
403
404 /* Register the read request */
405 mxcSemaCb.writeBuf = (uint8_t *)data;
406 mxcSemaCb.writeLen = len;
407 mxcSemaCb.writeCb = cb;
408
409 /* Pend the local interrupt to process the request */
410 #if TARGET_NUM == 32570 || TARGET_NUM == 32650 || TARGET_NUM == 32665
411 #ifdef __riscv
412 sema_regs->irq1 |= MXC_F_SEMA_REVA_IRQ1_RV32_IRQ;
413 #else
414 sema_regs->irq0 |= MXC_F_SEMA_REVA_IRQ0_CM4_IRQ;
415 #endif
416 #else
417 #ifdef __riscv
418 sema_regs->irq1 |= MXC_F_SEMA_IRQ1_RV32_IRQ;
419 #else
420 sema_regs->irq0 |= MXC_F_SEMA_IRQ0_CM4_IRQ;
421 #endif
422 #endif
423
424 return E_NO_ERROR;
425 }
426 }
427
MXC_SEMA_RevA_WriteHandler(mxc_sema_reva_regs_t * sema_regs)428 static int MXC_SEMA_RevA_WriteHandler(mxc_sema_reva_regs_t *sema_regs)
429 {
430 mxcSemaBox_t *writeBox;
431 unsigned writeAvailLen, writeLen, writeLenPart;
432 int err;
433
434 if (MAILBOX_SIZE == 0) {
435 return E_NONE_AVAIL;
436 } else {
437 /* Check to see if we have any pending read requests */
438 if (mxcSemaCb.writeBuf == NULL) {
439 return E_NO_ERROR;
440 }
441
442 /* Get the write semaphore */
443 err = E_BUSY;
444 while (err != E_NO_ERROR) {
445 err = MXC_SEMA_RevA_GetSema(sema_regs, SEMA_WRITE_SEMA);
446 }
447
448 /* Assign the writeBox pointer */
449 if (SEMA_WRITE_BOX == 1) {
450 writeBox = mxcSemaBox1;
451 } else if (SEMA_WRITE_BOX == 0) {
452 writeBox = mxcSemaBox0;
453 }
454
455 /* Check the available write length */
456 writeAvailLen = semaGetWriteBoxAvailLen();
457 if (mxcSemaCb.writeLen < writeAvailLen) {
458 writeLen = mxcSemaCb.writeLen;
459 } else {
460 writeLen = writeAvailLen;
461 }
462
463 /* Return without interrupting if not writing */
464 if (writeLen == 0) {
465 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_WRITE_SEMA);
466 return E_NO_ERROR;
467 }
468
469 /* Portion the write */
470 writeLenPart = 0;
471 if (writeLen > (MAILBOX_PAYLOAD_LEN - writeBox->writeLocation)) {
472 writeLenPart = (MAILBOX_PAYLOAD_LEN - writeBox->writeLocation);
473 semaWriteBox(sema_regs, writeBox, mxcSemaCb.writeBuf, writeLenPart);
474 mxcSemaCb.writeBuf += writeLenPart;
475 writeLen -= writeLenPart;
476 }
477
478 /* Complete the write */
479 semaWriteBox(sema_regs, writeBox, mxcSemaCb.writeBuf, writeLen);
480 mxcSemaCb.writeBuf += writeLen;
481 mxcSemaCb.writeLen -= (writeLenPart + writeLen);
482
483 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_WRITE_SEMA);
484
485 /* Call the callback if we're done with the read */
486 if (mxcSemaCb.writeLen == 0) {
487 mxcSemaCb.writeBuf = NULL;
488
489 if (mxcSemaCb.writeCb != NULL) {
490 mxcSemaCb.writeCb(E_NO_ERROR);
491 }
492 }
493
494 /* Interrupt the peer when we're done writing */
495 #if TARGET_NUM == 32570 || TARGET_NUM == 32650 || TARGET_NUM == 32665
496 #ifndef __riscv
497 sema_regs->irq1 |= MXC_F_SEMA_REVA_IRQ1_RV32_IRQ;
498 #else
499 sema_regs->irq0 |= MXC_F_SEMA_REVA_IRQ0_CM4_IRQ;
500 #endif
501 #else
502 #ifndef __riscv
503 sema_regs->irq1 |= MXC_F_SEMA_IRQ1_RV32_IRQ;
504 #else
505 sema_regs->irq0 |= MXC_F_SEMA_IRQ0_CM4_IRQ;
506 #endif
507 #endif
508
509 return E_NO_ERROR;
510 }
511 }
512
MXC_SEMA_RevA_ReadHandler(mxc_sema_reva_regs_t * sema_regs)513 static int MXC_SEMA_RevA_ReadHandler(mxc_sema_reva_regs_t *sema_regs)
514 {
515 int err;
516 unsigned readAvailLen, readLen, readLenPart;
517 mxcSemaBox_t *readBox;
518
519 /* Check to see if we have any pending read requests */
520 if (mxcSemaCb.readBuf == NULL) {
521 return E_NO_ERROR;
522 }
523
524 /* Get the read semaphore */
525 err = E_BUSY;
526 while (err != E_NO_ERROR) {
527 err = MXC_SEMA_RevA_GetSema(sema_regs, SEMA_READ_SEMA);
528 }
529
530 /* Assign the read box pointer */
531 if (SEMA_READ_BOX == 1) {
532 readBox = mxcSemaBox1;
533 } else if (SEMA_READ_BOX == 0) {
534 readBox = mxcSemaBox0;
535 }
536
537 /* Check the available read length */
538 readAvailLen = semaGetReadBoxAvailLen();
539 if (mxcSemaCb.readLen < readAvailLen) {
540 readLen = mxcSemaCb.readLen;
541 } else {
542 readLen = readAvailLen;
543 }
544
545 /* Return without interrupting if not reading */
546 if (readLen == 0) {
547 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_READ_SEMA);
548 return E_NO_ERROR;
549 }
550
551 /* Portion the read */
552 readLenPart = 0;
553 if (readBox->writeLocation < readBox->readLocation) {
554 /* Write location is behind the read location, wrap at the boundary */
555 if (readLen > (MAILBOX_PAYLOAD_LEN - readBox->readLocation)) {
556 readLenPart = (MAILBOX_PAYLOAD_LEN - readBox->readLocation);
557 semaReadBox(sema_regs, readBox, mxcSemaCb.readBuf, readLenPart);
558 mxcSemaCb.readBuf += readLenPart;
559 readLen -= readLenPart;
560 }
561 }
562
563 /* Complete the read */
564 semaReadBox(sema_regs, readBox, mxcSemaCb.readBuf, readLen);
565 mxcSemaCb.readBuf += readLen;
566 mxcSemaCb.readLen -= (readLenPart + readLen);
567
568 MXC_SEMA_RevA_FreeSema(sema_regs, SEMA_READ_SEMA);
569
570 /* Call the callback if we're done with the read */
571 if (mxcSemaCb.readLen == 0) {
572 mxcSemaCb.readBuf = NULL;
573
574 if (mxcSemaCb.readCb != NULL) {
575 mxcSemaCb.readCb(E_NO_ERROR);
576 }
577 }
578
579 /* Interrupt the peer when we're done reading */
580 #if TARGET_NUM == 32570 || TARGET_NUM == 32650 || TARGET_NUM == 32665
581 #ifndef __riscv
582 sema_regs->irq1 |= MXC_F_SEMA_REVA_IRQ1_RV32_IRQ;
583 #else
584 sema_regs->irq0 |= MXC_F_SEMA_REVA_IRQ0_CM4_IRQ;
585 #endif
586 #else
587 #ifndef __riscv
588 sema_regs->irq1 |= MXC_F_SEMA_IRQ1_RV32_IRQ;
589 #else
590 sema_regs->irq0 |= MXC_F_SEMA_IRQ0_CM4_IRQ;
591 #endif
592 #endif
593
594 return E_NO_ERROR;
595 }
596
MXC_SEMA_RevA_Handler(mxc_sema_reva_regs_t * sema_regs)597 int MXC_SEMA_RevA_Handler(mxc_sema_reva_regs_t *sema_regs)
598 {
599 int err = 0;
600
601 /* Process any pending read requests */
602 err |= MXC_SEMA_RevA_ReadHandler(sema_regs);
603
604 /* Process any pending write requests */
605 err |= MXC_SEMA_RevA_WriteHandler(sema_regs);
606
607 return err;
608 }
609