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