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