1 /*
2 * Copyright (c) 2016 - 2017, Xilinx Inc. and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /*
8 * @file freertos/xlnx/irq.c
9 * @brief freertos libmetal Xilinx irq controller definitions.
10 */
11
12 #include <metal/errno.h>
13 #include <metal/irq_controller.h>
14 #include <metal/sys.h>
15 #include <metal/log.h>
16 #include <metal/mutex.h>
17 #include <metal/list.h>
18 #include <metal/utilities.h>
19 #include <metal/alloc.h>
20 #include <metal/system/freertos/xlnx/sys.h>
21
22 #define MAX_IRQS XLNX_MAXIRQS
23
24 static struct metal_irq irqs[MAX_IRQS]; /**< Linux IRQs array */
25
metal_xlnx_irq_set_enable(struct metal_irq_controller * irq_cntr,int irq,unsigned int state)26 static void metal_xlnx_irq_set_enable(struct metal_irq_controller *irq_cntr,
27 int irq, unsigned int state)
28 {
29 if (irq < irq_cntr->irq_base ||
30 irq >= irq_cntr->irq_base + irq_cntr->irq_num) {
31 metal_log(METAL_LOG_ERROR, "%s: invalid irq %d\n",
32 __func__, irq);
33 return;
34 } else if (state == METAL_IRQ_ENABLE) {
35 sys_irq_enable((unsigned int)irq);
36 } else {
37 sys_irq_disable((unsigned int)irq);
38 }
39 }
40
41 /**< Xilinx common platform IRQ controller */
42 static METAL_IRQ_CONTROLLER_DECLARE(xlnx_irq_cntr,
43 0, MAX_IRQS,
44 NULL,
45 metal_xlnx_irq_set_enable, NULL,
46 irqs);
47
48 /**
49 * @brief default handler
50 */
metal_xlnx_irq_isr(void * arg)51 void metal_xlnx_irq_isr(void *arg)
52 {
53 unsigned int vector;
54
55 vector = (uintptr_t)arg;
56 if (vector >= MAX_IRQS) {
57 return;
58 }
59 (void)metal_irq_handle(&irqs[vector], (int)vector);
60 }
61
metal_xlnx_irq_init(void)62 int metal_xlnx_irq_init(void)
63 {
64 int ret;
65
66 ret = metal_irq_register_controller(&xlnx_irq_cntr);
67 if (ret < 0) {
68 metal_log(METAL_LOG_ERROR, "%s: register irq controller failed.\n",
69 __func__);
70 return ret;
71 }
72 return 0;
73 }
74