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 void itr_init(struct itr_chip *data); 61 void itr_handle(size_t it); 62 63 #ifdef CFG_DT 64 /* 65 * Get the DT interrupt property at @node. In the DT an interrupt property can 66 * specify additional information which can be retrieved with @type and @prio. 67 * 68 * @fdt reference to the Device Tree 69 * @node is the node offset to read the interrupt property from 70 * @type interrupt type (IRQ_TYPE_* defines) if specified by interrupt property 71 * or IRQ_TYPE_NONE if not. Can be NULL if not needed 72 * @prio interrupt priority if specified by interrupt property or 0 if not. Can 73 * be NULL if not needed 74 * 75 * Returns the interrupt number if value >= 0 76 * otherwise DT_INFO_INVALID_INTERRUPT 77 */ 78 int dt_get_irq_type_prio(const void *fdt, int node, uint32_t *type, 79 uint32_t *prio); 80 81 /* 82 * Get the DT interrupt property at @node 83 */ 84 static inline int dt_get_irq(const void *fdt, int node) 85 { 86 return dt_get_irq_type_prio(fdt, node, NULL, NULL); 87 } 88 #endif 89 90 struct itr_handler *itr_alloc_add_type_prio(size_t it, itr_handler_t handler, 91 uint32_t flags, void *data, 92 uint32_t type, uint32_t prio); 93 void itr_free(struct itr_handler *hdl); 94 void itr_add_type_prio(struct itr_handler *handler, uint32_t type, 95 uint32_t prio); 96 void itr_enable(size_t it); 97 void itr_disable(size_t it); 98 /* raise the Peripheral Interrupt corresponding to the interrupt ID */ 99 void itr_raise_pi(size_t it); 100 /* 101 * raise the Software Generated Interrupt corresponding to the interrupt ID, 102 * the cpu_mask represents which cpu interface to forward. 103 */ 104 void itr_raise_sgi(size_t it, uint8_t cpu_mask); 105 /* 106 * let corresponding interrupt forward to the cpu interface 107 * according to the cpu_mask. 108 */ 109 void itr_set_affinity(size_t it, uint8_t cpu_mask); 110 111 /* 112 * __weak overridable function which is called when a secure interrupt is 113 * received. The default function calls panic() immediately, platforms which 114 * expects to receive secure interrupts should override this function. 115 */ 116 void itr_core_handler(void); 117 118 static inline void itr_add(struct itr_handler *handler) 119 { 120 itr_add_type_prio(handler, IRQ_TYPE_NONE, 0); 121 } 122 123 static inline struct itr_handler *itr_alloc_add(size_t it, 124 itr_handler_t handler, 125 uint32_t flags, void *data) 126 { 127 return itr_alloc_add_type_prio(it, handler, flags, data, IRQ_TYPE_NONE, 128 0); 129 } 130 131 #endif /*__KERNEL_INTERRUPT_H*/ 132