1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2016-2019, Linaro Limited 4 */ 5 #ifndef __KERNEL_INTERRUPT_H 6 #define __KERNEL_INTERRUPT_H 7 8 #include <dt-bindings/interrupt-controller/irq.h> 9 #include <types_ext.h> 10 #include <sys/queue.h> 11 #include <util.h> 12 13 #define ITRF_TRIGGER_LEVEL BIT(0) 14 #define ITRF_SHARED BIT(1) 15 16 /* 17 * struct itr_chip - Interrupt controller 18 * 19 * @ops Operation callback functions 20 * @dt_get_irq Device tree node parsing function 21 */ 22 struct itr_chip { 23 const struct itr_ops *ops; 24 /* 25 * dt_get_irq - parse a device tree interrupt property 26 * 27 * @properties raw interrupt property from device tree 28 * @count number of elements in @properties 29 * @type If not NULL, output interrupt type (IRQ_TYPE_* defines) 30 * or IRQ_TYPE_NONE if unknown 31 * @prio If not NULL, output interrupt priority value or 0 if unknown 32 */ 33 int (*dt_get_irq)(const uint32_t *properties, int count, uint32_t *type, 34 uint32_t *prio); 35 }; 36 37 /* 38 * struct itr_ops - Interrupt controller operations 39 * @add Register and configure an interrupt 40 * @enable Enable an interrupt 41 * @disable Disable an interrupt 42 * @raise_pi Raise per-cpu interrupt or NULL if not applicable 43 * @raise_sgi Raise a SGI or NULL if not applicable to that controller 44 * @set_affinity Set interrupt/cpu affinity or NULL if not applicable 45 */ 46 struct itr_ops { 47 void (*add)(struct itr_chip *chip, size_t it, uint32_t type, 48 uint32_t prio); 49 void (*enable)(struct itr_chip *chip, size_t it); 50 void (*disable)(struct itr_chip *chip, size_t it); 51 void (*raise_pi)(struct itr_chip *chip, size_t it); 52 void (*raise_sgi)(struct itr_chip *chip, size_t it, 53 uint8_t cpu_mask); 54 void (*set_affinity)(struct itr_chip *chip, size_t it, 55 uint8_t cpu_mask); 56 }; 57 58 /* Interrupt handler return value */ 59 enum itr_return { 60 ITRR_NONE, 61 ITRR_HANDLED, 62 }; 63 64 struct itr_handler; 65 66 /* Interrupt handler signature */ 67 typedef enum itr_return (*itr_handler_t)(struct itr_handler *h); 68 69 /* 70 * struct itr_handler - Interrupt handler reference 71 * @it Interrupt number 72 * @flags Property bit flags ITR_FLAG_* 73 * @data Private data for that interrupt handler 74 * @link Reference in controller handler list 75 */ 76 struct itr_handler { 77 size_t it; 78 uint32_t flags; 79 itr_handler_t handler; 80 void *data; 81 SLIST_ENTRY(itr_handler) link; 82 }; 83 84 /* 85 * Initialise main interrupt controller driver 86 * @data Main controller main data reference to register 87 */ 88 void interrupt_main_init(struct itr_chip *data); 89 90 /* 91 * Call handlers registered for that interrupt in core interrupt controller 92 * @it Interrupt line number 93 */ 94 void itr_handle(size_t it); 95 96 /* Retrieve main interrupt controller reference */ 97 struct itr_chip *interrupt_get_main_chip(void); 98 99 #ifdef CFG_DT 100 /* 101 * Get the DT interrupt property at @node. In the DT an interrupt property can 102 * specify additional information which can be retrieved with @type and @prio. 103 * 104 * @fdt reference to the Device Tree 105 * @node is the node offset to read the interrupt property from 106 * @type interrupt type (IRQ_TYPE_* defines) if specified by interrupt property 107 * or IRQ_TYPE_NONE if not. Can be NULL if not needed 108 * @prio interrupt priority if specified by interrupt property or 0 if not. Can 109 * be NULL if not needed 110 * 111 * Returns the interrupt number if value >= 0 112 * otherwise DT_INFO_INVALID_INTERRUPT 113 */ 114 int dt_get_irq_type_prio(const void *fdt, int node, uint32_t *type, 115 uint32_t *prio); 116 117 /* 118 * Get the DT interrupt property at @node 119 */ 120 static inline int dt_get_irq(const void *fdt, int node) 121 { 122 return dt_get_irq_type_prio(fdt, node, NULL, NULL); 123 } 124 #endif 125 126 struct itr_handler *itr_alloc_add_type_prio(size_t it, itr_handler_t handler, 127 uint32_t flags, void *data, 128 uint32_t type, uint32_t prio); 129 void itr_free(struct itr_handler *hdl); 130 void itr_add_type_prio(struct itr_handler *handler, uint32_t type, 131 uint32_t prio); 132 void itr_enable(size_t it); 133 void itr_disable(size_t it); 134 /* raise the Peripheral Interrupt corresponding to the interrupt ID */ 135 void itr_raise_pi(size_t it); 136 /* 137 * raise the Software Generated Interrupt corresponding to the interrupt ID, 138 * the cpu_mask represents which cpu interface to forward. 139 */ 140 void itr_raise_sgi(size_t it, uint8_t cpu_mask); 141 /* 142 * let corresponding interrupt forward to the cpu interface 143 * according to the cpu_mask. 144 */ 145 void itr_set_affinity(size_t it, uint8_t cpu_mask); 146 147 /* 148 * __weak overridable function which is called when a secure interrupt is 149 * received. The default function calls panic() immediately, platforms which 150 * expects to receive secure interrupts should override this function. 151 */ 152 void interrupt_main_handler(void); 153 154 static inline void itr_add(struct itr_handler *handler) 155 { 156 itr_add_type_prio(handler, IRQ_TYPE_NONE, 0); 157 } 158 159 static inline struct itr_handler *itr_alloc_add(size_t it, 160 itr_handler_t handler, 161 uint32_t flags, void *data) 162 { 163 return itr_alloc_add_type_prio(it, handler, flags, data, IRQ_TYPE_NONE, 164 0); 165 } 166 167 #endif /*__KERNEL_INTERRUPT_H*/ 168