1 /*
2  * Copyright (C) 2021-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef COMMON_IRQ_H
8 #define COMMON_IRQ_H
9 
10 #include <lib/util.h>
11 #include <asm/lib/spinlock.h>
12 
13 /**
14  * @file common/irq.h
15  *
16  * @brief public APIs for common IRQ handling
17  */
18 
19 #define NR_IRQS			256U
20 #define IRQ_INVALID		0xffffffffU
21 
22 #define IRQ_ALLOC_BITMAP_SIZE	INT_DIV_ROUNDUP(NR_IRQS, 64U)
23 
24 #define IRQF_NONE	(0U)
25 #define IRQF_LEVEL	(1U << 1U)	/* 1: level trigger; 0: edge trigger */
26 #define IRQF_PT		(1U << 2U)	/* 1: for passthrough dev */
27 
28 extern uint64_t irq_alloc_bitmap[IRQ_ALLOC_BITMAP_SIZE];
29 
30 typedef void (*irq_action_t)(uint32_t irq, void *priv_data);
31 
32 /**
33  * @brief Interrupt descriptor
34  *
35  * Any field change in below required lock protection with irqsave
36  */
37 struct irq_desc {
38 	uint32_t irq;		/**< index to irq_desc_base */
39 
40 	void *arch_data;	/**< arch-specific data */
41 
42 	irq_action_t action;	/**< callback registered from component */
43 	void *priv_data;	/**< irq_action private data */
44 	uint32_t flags;		/**< flags for trigger mode/ptdev */
45 
46 	spinlock_t lock;
47 };
48 
49 /**
50  * @defgroup phys_int_ext_apis Physical Interrupt External Interfaces
51  *
52  * This is a group that includes Physical Interrupt External Interfaces.
53  *
54  * @{
55  */
56 
57 /**
58  * @brief Reserve an interrupt num
59  *
60  * Reserved interrupt num will not be available for dynamic IRQ allocations.
61  * This is normally used by the hypervisor for static IRQ mappings and/or
62  * arch specific, e.g. IOAPIC, interrupts during initialization.
63  *
64  * @param[in]	req_irq	irq_num to be reserved
65  *
66  * @retval >=0 on success, IRQ_INVALID on failure
67  */
68 uint32_t reserve_irq_num(uint32_t req_irq);
69 
70 /**
71  * @brief Request an interrupt
72  *
73  * Request interrupt num if not specified, and register irq action for the
74  * specified/allocated irq.
75  *
76  * @param[in]	req_irq	irq_num to request, if IRQ_INVALID, a free irq
77  *		number will be allocated
78  * @param[in]	action_fn	Function to be called when the IRQ occurs
79  * @param[in]	priv_data	Private data for action function.
80  * @param[in]	flags	Interrupt type flags, including:
81  *			IRQF_NONE;
82  *			IRQF_LEVEL - 1: level trigger; 0: edge trigger;
83  *			IRQF_PT    - 1: for passthrough dev
84  *
85  * @retval >=0 on success
86  * @retval IRQ_INVALID on failure
87  */
88 int32_t request_irq(uint32_t req_irq, irq_action_t action_fn, void *priv_data,
89 			uint32_t flags);
90 
91 /**
92  * @brief Free an interrupt
93  *
94  * Free irq num and unregister the irq action.
95  *
96  * @param[in]	irq	irq_num to be freed
97  */
98 void free_irq(uint32_t irq);
99 
100 /**
101  * @brief Set interrupt trigger mode
102  *
103  * Set the irq trigger mode: edge-triggered or level-triggered
104  *
105  * @param[in]	irq	irq_num of interrupt to be set
106  * @param[in]	is_level_triggered	Trigger mode to set
107  */
108 void set_irq_trigger_mode(uint32_t irq, bool is_level_triggered);
109 
110 /**
111  * @brief Process an IRQ
112  *
113  * To process an IRQ, an action callback will be called if registered.
114  *
115  * @param irq     irq_num to be processed
116  */
117 void do_irq(const uint32_t irq);
118 
119 /**
120  * @brief Initialize interrupt
121  *
122  * To do interrupt initialization for a cpu, will be called for each physical cpu.
123  *
124  * @param[in]	pcpu_id The id of physical cpu to initialize
125  */
126 void init_interrupt(uint16_t pcpu_id);
127 
128 
129 /**
130  * @}
131  */
132 /* End of phys_int_ext_apis */
133 
134 #endif /* COMMON_IRQ_H */
135