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 struct itr_chip { 17 const struct itr_ops *ops; 18 /* 19 * dt_get_irq - parse a device tree interrupt property 20 * 21 * @properties raw interrupt property from device tree 22 * @count number of elements in @properties 23 * @type If not NULL, output interrupt type (IRQ_TYPE_* defines) 24 * or IRQ_TYPE_NONE if unknown 25 * @prio If not NULL, output interrupt priority value or 0 if unknown 26 */ 27 int (*dt_get_irq)(const uint32_t *properties, int count, uint32_t *type, 28 uint32_t *prio); 29 }; 30 31 struct itr_ops { 32 void (*add)(struct itr_chip *chip, size_t it, uint32_t type, 33 uint32_t prio); 34 void (*enable)(struct itr_chip *chip, size_t it); 35 void (*disable)(struct itr_chip *chip, size_t it); 36 void (*raise_pi)(struct itr_chip *chip, size_t it); 37 void (*raise_sgi)(struct itr_chip *chip, size_t it, 38 uint8_t cpu_mask); 39 void (*set_affinity)(struct itr_chip *chip, size_t it, 40 uint8_t cpu_mask); 41 }; 42 43 enum itr_return { 44 ITRR_NONE, 45 ITRR_HANDLED, 46 }; 47 48 struct itr_handler; 49 50 typedef enum itr_return (*itr_handler_t)(struct itr_handler *h); 51 52 struct itr_handler { 53 size_t it; 54 uint32_t flags; 55 itr_handler_t handler; 56 void *data; 57 SLIST_ENTRY(itr_handler) link; 58 }; 59 60 /* 61 * Initialise core interrupt controller driver 62 * @data Core controller main data reference to register 63 */ 64 void interrupt_main_init(struct itr_chip *data); 65 66 void itr_handle(size_t it); 67 68 /* Retrieve main interrupt controller reference */ 69 struct itr_chip *interrupt_get_main_chip(void); 70 71 #ifdef CFG_DT 72 /* 73 * Get the DT interrupt property at @node. In the DT an interrupt property can 74 * specify additional information which can be retrieved with @type and @prio. 75 * 76 * @fdt reference to the Device Tree 77 * @node is the node offset to read the interrupt property from 78 * @type interrupt type (IRQ_TYPE_* defines) if specified by interrupt property 79 * or IRQ_TYPE_NONE if not. Can be NULL if not needed 80 * @prio interrupt priority if specified by interrupt property or 0 if not. Can 81 * be NULL if not needed 82 * 83 * Returns the interrupt number if value >= 0 84 * otherwise DT_INFO_INVALID_INTERRUPT 85 */ 86 int dt_get_irq_type_prio(const void *fdt, int node, uint32_t *type, 87 uint32_t *prio); 88 89 /* 90 * Get the DT interrupt property at @node 91 */ 92 static inline int dt_get_irq(const void *fdt, int node) 93 { 94 return dt_get_irq_type_prio(fdt, node, NULL, NULL); 95 } 96 #endif 97 98 struct itr_handler *itr_alloc_add_type_prio(size_t it, itr_handler_t handler, 99 uint32_t flags, void *data, 100 uint32_t type, uint32_t prio); 101 void itr_free(struct itr_handler *hdl); 102 void itr_add_type_prio(struct itr_handler *handler, uint32_t type, 103 uint32_t prio); 104 void itr_enable(size_t it); 105 void itr_disable(size_t it); 106 /* raise the Peripheral Interrupt corresponding to the interrupt ID */ 107 void itr_raise_pi(size_t it); 108 /* 109 * raise the Software Generated Interrupt corresponding to the interrupt ID, 110 * the cpu_mask represents which cpu interface to forward. 111 */ 112 void itr_raise_sgi(size_t it, uint8_t cpu_mask); 113 /* 114 * let corresponding interrupt forward to the cpu interface 115 * according to the cpu_mask. 116 */ 117 void itr_set_affinity(size_t it, uint8_t cpu_mask); 118 119 /* 120 * __weak overridable function which is called when a secure interrupt is 121 * received. The default function calls panic() immediately, platforms which 122 * expects to receive secure interrupts should override this function. 123 */ 124 void interrupt_main_handler(void); 125 126 static inline void itr_add(struct itr_handler *handler) 127 { 128 itr_add_type_prio(handler, IRQ_TYPE_NONE, 0); 129 } 130 131 static inline struct itr_handler *itr_alloc_add(size_t it, 132 itr_handler_t handler, 133 uint32_t flags, void *data) 134 { 135 return itr_alloc_add_type_prio(it, handler, flags, data, IRQ_TYPE_NONE, 136 0); 137 } 138 139 #endif /*__KERNEL_INTERRUPT_H*/ 140