11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */ 27315b7b4SJens Wiklander /* 3e9f46c74SJens Wiklander * Copyright (c) 2016-2019, Linaro Limited 47315b7b4SJens Wiklander */ 57315b7b4SJens Wiklander #ifndef __KERNEL_INTERRUPT_H 67315b7b4SJens Wiklander #define __KERNEL_INTERRUPT_H 77315b7b4SJens Wiklander 8702fe5a7SClément Léger #include <dt-bindings/interrupt-controller/irq.h> 9f932e355SEtienne Carriere #include <mm/core_memprot.h> 107315b7b4SJens Wiklander #include <sys/queue.h> 11f932e355SEtienne Carriere #include <tee_api_types.h> 12f932e355SEtienne Carriere #include <types_ext.h> 131c832d7cSdavidwang #include <util.h> 147315b7b4SJens Wiklander 151c832d7cSdavidwang #define ITRF_TRIGGER_LEVEL BIT(0) 161c832d7cSdavidwang #define ITRF_SHARED BIT(1) 177315b7b4SJens Wiklander 18f932e355SEtienne Carriere struct itr_handler; 19f932e355SEtienne Carriere 20a009881dSEtienne Carriere /* 21a009881dSEtienne Carriere * struct itr_chip - Interrupt controller 22a009881dSEtienne Carriere * 23a009881dSEtienne Carriere * @ops Operation callback functions 24f932e355SEtienne Carriere * @name Controller name, for debug purpose 25f932e355SEtienne Carriere * @handlers Registered handlers list head 26a009881dSEtienne Carriere * @dt_get_irq Device tree node parsing function 27a009881dSEtienne Carriere */ 287315b7b4SJens Wiklander struct itr_chip { 297315b7b4SJens Wiklander const struct itr_ops *ops; 30f932e355SEtienne Carriere const char *name; 31f932e355SEtienne Carriere SLIST_HEAD(, itr_handler) handlers; 32702fe5a7SClément Léger /* 33702fe5a7SClément Léger * dt_get_irq - parse a device tree interrupt property 34702fe5a7SClément Léger * 35702fe5a7SClément Léger * @properties raw interrupt property from device tree 36702fe5a7SClément Léger * @count number of elements in @properties 37702fe5a7SClément Léger * @type If not NULL, output interrupt type (IRQ_TYPE_* defines) 38702fe5a7SClément Léger * or IRQ_TYPE_NONE if unknown 39702fe5a7SClément Léger * @prio If not NULL, output interrupt priority value or 0 if unknown 40702fe5a7SClément Léger */ 41702fe5a7SClément Léger int (*dt_get_irq)(const uint32_t *properties, int count, uint32_t *type, 42702fe5a7SClément Léger uint32_t *prio); 437315b7b4SJens Wiklander }; 447315b7b4SJens Wiklander 45a009881dSEtienne Carriere /* 46a009881dSEtienne Carriere * struct itr_ops - Interrupt controller operations 47a009881dSEtienne Carriere * @add Register and configure an interrupt 48a009881dSEtienne Carriere * @enable Enable an interrupt 49a009881dSEtienne Carriere * @disable Disable an interrupt 50f932e355SEtienne Carriere * @mask Mask an interrupt, may be called from an interrupt context 51f932e355SEtienne Carriere * @unmask Unmask an interrupt, may be called from an interrupt context 52a009881dSEtienne Carriere * @raise_pi Raise per-cpu interrupt or NULL if not applicable 53a009881dSEtienne Carriere * @raise_sgi Raise a SGI or NULL if not applicable to that controller 54a009881dSEtienne Carriere * @set_affinity Set interrupt/cpu affinity or NULL if not applicable 55f932e355SEtienne Carriere * 56f932e355SEtienne Carriere * Handlers @enable, @disable, @mask, @unmask and @add are mandated. Handlers 57f932e355SEtienne Carriere * @mask and @unmask have unpaged memory contrainsts. See itr_chip_is_valid(). 58a009881dSEtienne Carriere */ 597315b7b4SJens Wiklander struct itr_ops { 60702fe5a7SClément Léger void (*add)(struct itr_chip *chip, size_t it, uint32_t type, 61702fe5a7SClément Léger uint32_t prio); 627315b7b4SJens Wiklander void (*enable)(struct itr_chip *chip, size_t it); 637315b7b4SJens Wiklander void (*disable)(struct itr_chip *chip, size_t it); 64f932e355SEtienne Carriere void (*mask)(struct itr_chip *chip, size_t it); 65f932e355SEtienne Carriere void (*unmask)(struct itr_chip *chip, size_t it); 6626ed70ecSGuanchao Liang void (*raise_pi)(struct itr_chip *chip, size_t it); 6726ed70ecSGuanchao Liang void (*raise_sgi)(struct itr_chip *chip, size_t it, 6826ed70ecSGuanchao Liang uint8_t cpu_mask); 6926ed70ecSGuanchao Liang void (*set_affinity)(struct itr_chip *chip, size_t it, 7026ed70ecSGuanchao Liang uint8_t cpu_mask); 717315b7b4SJens Wiklander }; 727315b7b4SJens Wiklander 73a009881dSEtienne Carriere /* Interrupt handler return value */ 747315b7b4SJens Wiklander enum itr_return { 757315b7b4SJens Wiklander ITRR_NONE, 767315b7b4SJens Wiklander ITRR_HANDLED, 777315b7b4SJens Wiklander }; 787315b7b4SJens Wiklander 79a009881dSEtienne Carriere /* Interrupt handler signature */ 80acc5dd21SLudovic Barre typedef enum itr_return (*itr_handler_t)(struct itr_handler *h); 81acc5dd21SLudovic Barre 82a009881dSEtienne Carriere /* 83a009881dSEtienne Carriere * struct itr_handler - Interrupt handler reference 84a009881dSEtienne Carriere * @it Interrupt number 85f932e355SEtienne Carriere * @flags Property bit flags (ITRF_*) or 0 86a009881dSEtienne Carriere * @data Private data for that interrupt handler 87f932e355SEtienne Carriere * @chip Interrupt controller chip device 88a009881dSEtienne Carriere * @link Reference in controller handler list 89a009881dSEtienne Carriere */ 907315b7b4SJens Wiklander struct itr_handler { 917315b7b4SJens Wiklander size_t it; 927315b7b4SJens Wiklander uint32_t flags; 93acc5dd21SLudovic Barre itr_handler_t handler; 947315b7b4SJens Wiklander void *data; 95f932e355SEtienne Carriere struct itr_chip *chip; 967315b7b4SJens Wiklander SLIST_ENTRY(itr_handler) link; 977315b7b4SJens Wiklander }; 987315b7b4SJens Wiklander 99f932e355SEtienne Carriere #define ITR_HANDLER(_chip, _itr_num, _flags, _fn, _priv) \ 100f932e355SEtienne Carriere ((struct itr_handler){ \ 101f932e355SEtienne Carriere .chip = (_chip), .it = (_itr_num), .flags = (_flags), \ 102f932e355SEtienne Carriere .handler = (_fn), .data = (_priv), \ 103f932e355SEtienne Carriere }) 104f932e355SEtienne Carriere 105f932e355SEtienne Carriere /* 106f932e355SEtienne Carriere * Return true only if interrupt chip provides required handlers 107f932e355SEtienne Carriere * @chip: Interrupt controller reference 108f932e355SEtienne Carriere */ 109f932e355SEtienne Carriere static inline bool itr_chip_is_valid(struct itr_chip *chip) 110f932e355SEtienne Carriere { 111f932e355SEtienne Carriere return chip && is_unpaged(chip) && chip->ops && 112f932e355SEtienne Carriere is_unpaged((void *)chip->ops) && 113f932e355SEtienne Carriere chip->ops->mask && is_unpaged(chip->ops->mask) && 114f932e355SEtienne Carriere chip->ops->unmask && is_unpaged(chip->ops->unmask) && 115f932e355SEtienne Carriere chip->ops->enable && chip->ops->disable && 116f932e355SEtienne Carriere chip->ops->add; 117f932e355SEtienne Carriere } 118f932e355SEtienne Carriere 119f932e355SEtienne Carriere /* 120f932e355SEtienne Carriere * Initialise an interrupt controller handle 121f932e355SEtienne Carriere * @chip Interrupt controller 122f932e355SEtienne Carriere */ 123f932e355SEtienne Carriere TEE_Result itr_chip_init(struct itr_chip *chip); 124f932e355SEtienne Carriere 12501980f3fSEtienne Carriere /* 126a009881dSEtienne Carriere * Initialise main interrupt controller driver 127a009881dSEtienne Carriere * @data Main controller main data reference to register 12801980f3fSEtienne Carriere */ 12901980f3fSEtienne Carriere void interrupt_main_init(struct itr_chip *data); 13001980f3fSEtienne Carriere 131e050e0a7SEtienne Carriere /* Retrieve main interrupt controller reference */ 132e050e0a7SEtienne Carriere struct itr_chip *interrupt_get_main_chip(void); 133e050e0a7SEtienne Carriere 13467729d8dSLudovic Barre #ifdef CFG_DT 13567729d8dSLudovic Barre /* 136702fe5a7SClément Léger * Get the DT interrupt property at @node. In the DT an interrupt property can 137702fe5a7SClément Léger * specify additional information which can be retrieved with @type and @prio. 13867729d8dSLudovic Barre * 13967729d8dSLudovic Barre * @fdt reference to the Device Tree 140702fe5a7SClément Léger * @node is the node offset to read the interrupt property from 141702fe5a7SClément Léger * @type interrupt type (IRQ_TYPE_* defines) if specified by interrupt property 142702fe5a7SClément Léger * or IRQ_TYPE_NONE if not. Can be NULL if not needed 143702fe5a7SClément Léger * @prio interrupt priority if specified by interrupt property or 0 if not. Can 144702fe5a7SClément Léger * be NULL if not needed 14567729d8dSLudovic Barre * 14667729d8dSLudovic Barre * Returns the interrupt number if value >= 0 14767729d8dSLudovic Barre * otherwise DT_INFO_INVALID_INTERRUPT 14867729d8dSLudovic Barre */ 149702fe5a7SClément Léger int dt_get_irq_type_prio(const void *fdt, int node, uint32_t *type, 150702fe5a7SClément Léger uint32_t *prio); 151702fe5a7SClément Léger 152702fe5a7SClément Léger /* 153702fe5a7SClément Léger * Get the DT interrupt property at @node 154702fe5a7SClément Léger */ 155702fe5a7SClément Léger static inline int dt_get_irq(const void *fdt, int node) 156702fe5a7SClément Léger { 157702fe5a7SClément Léger return dt_get_irq_type_prio(fdt, node, NULL, NULL); 158702fe5a7SClément Léger } 15967729d8dSLudovic Barre #endif 16067729d8dSLudovic Barre 161702fe5a7SClément Léger struct itr_handler *itr_alloc_add_type_prio(size_t it, itr_handler_t handler, 162702fe5a7SClément Léger uint32_t flags, void *data, 163702fe5a7SClément Léger uint32_t type, uint32_t prio); 164acc5dd21SLudovic Barre void itr_free(struct itr_handler *hdl); 165702fe5a7SClément Léger void itr_add_type_prio(struct itr_handler *handler, uint32_t type, 166702fe5a7SClément Léger uint32_t prio); 16726ed70ecSGuanchao Liang void itr_enable(size_t it); 16826ed70ecSGuanchao Liang void itr_disable(size_t it); 16926ed70ecSGuanchao Liang /* raise the Peripheral Interrupt corresponding to the interrupt ID */ 17026ed70ecSGuanchao Liang void itr_raise_pi(size_t it); 17126ed70ecSGuanchao Liang /* 17226ed70ecSGuanchao Liang * raise the Software Generated Interrupt corresponding to the interrupt ID, 17326ed70ecSGuanchao Liang * the cpu_mask represents which cpu interface to forward. 17426ed70ecSGuanchao Liang */ 17526ed70ecSGuanchao Liang void itr_raise_sgi(size_t it, uint8_t cpu_mask); 17626ed70ecSGuanchao Liang /* 17726ed70ecSGuanchao Liang * let corresponding interrupt forward to the cpu interface 17826ed70ecSGuanchao Liang * according to the cpu_mask. 17926ed70ecSGuanchao Liang */ 18026ed70ecSGuanchao Liang void itr_set_affinity(size_t it, uint8_t cpu_mask); 1817315b7b4SJens Wiklander 182e9f46c74SJens Wiklander /* 183e9f46c74SJens Wiklander * __weak overridable function which is called when a secure interrupt is 184e9f46c74SJens Wiklander * received. The default function calls panic() immediately, platforms which 185e9f46c74SJens Wiklander * expects to receive secure interrupts should override this function. 186e9f46c74SJens Wiklander */ 187358bf47cSEtienne Carriere void interrupt_main_handler(void); 188e9f46c74SJens Wiklander 189702fe5a7SClément Léger static inline void itr_add(struct itr_handler *handler) 190702fe5a7SClément Léger { 191702fe5a7SClément Léger itr_add_type_prio(handler, IRQ_TYPE_NONE, 0); 192702fe5a7SClément Léger } 193702fe5a7SClément Léger 194702fe5a7SClément Léger static inline struct itr_handler *itr_alloc_add(size_t it, 195702fe5a7SClément Léger itr_handler_t handler, 196702fe5a7SClément Léger uint32_t flags, void *data) 197702fe5a7SClément Léger { 198702fe5a7SClément Léger return itr_alloc_add_type_prio(it, handler, flags, data, IRQ_TYPE_NONE, 199702fe5a7SClément Léger 0); 200702fe5a7SClément Léger } 201702fe5a7SClément Léger 202f932e355SEtienne Carriere /* 203f932e355SEtienne Carriere * Interrupt controller chip API functions 204f932e355SEtienne Carriere */ 205f932e355SEtienne Carriere 206f932e355SEtienne Carriere /* 207f932e355SEtienne Carriere * interrupt_call_handlers() - Call registered handlers for an interrupt 208f932e355SEtienne Carriere * @chip Interrupt controller 209f932e355SEtienne Carriere * @itr_num Interrupt number 210f932e355SEtienne Carriere * 211f932e355SEtienne Carriere * This function is called from an interrupt context by a primary interrupt 212f932e355SEtienne Carriere * handler. This function calls the handlers registered for that interrupt. 213f932e355SEtienne Carriere * If interrupt is not handled, it is masked. 214f932e355SEtienne Carriere */ 215f932e355SEtienne Carriere void interrupt_call_handlers(struct itr_chip *chip, size_t itr_num); 216f932e355SEtienne Carriere 217f932e355SEtienne Carriere /* 218f932e355SEtienne Carriere * interrupt_mask() - Mask an interrupt 219f932e355SEtienne Carriere * @chip Interrupt controller 220f932e355SEtienne Carriere * @itr_num Interrupt number 221f932e355SEtienne Carriere * 222f932e355SEtienne Carriere * This function may be called in interrupt context 223f932e355SEtienne Carriere */ 224f932e355SEtienne Carriere static inline void interrupt_mask(struct itr_chip *chip, size_t itr_num) 225f932e355SEtienne Carriere { 226f932e355SEtienne Carriere chip->ops->mask(chip, itr_num); 227f932e355SEtienne Carriere } 228f932e355SEtienne Carriere 229f932e355SEtienne Carriere /* 230f932e355SEtienne Carriere * interrupt_unmask() - Unmask an interrupt 231f932e355SEtienne Carriere * @chip Interrupt controller 232f932e355SEtienne Carriere * @itr_num Interrupt number 233f932e355SEtienne Carriere * 234f932e355SEtienne Carriere * This function may be called in interrupt context 235f932e355SEtienne Carriere */ 236f932e355SEtienne Carriere static inline void interrupt_unmask(struct itr_chip *chip, size_t itr_num) 237f932e355SEtienne Carriere { 238f932e355SEtienne Carriere chip->ops->unmask(chip, itr_num); 239f932e355SEtienne Carriere } 240f932e355SEtienne Carriere 241f932e355SEtienne Carriere /* 242f932e355SEtienne Carriere * interrupt_enable() - Enable an interrupt 243f932e355SEtienne Carriere * @chip Interrupt controller 244f932e355SEtienne Carriere * @itr_num Interrupt number 245f932e355SEtienne Carriere */ 246f932e355SEtienne Carriere static inline void interrupt_enable(struct itr_chip *chip, size_t itr_num) 247f932e355SEtienne Carriere { 248f932e355SEtienne Carriere chip->ops->enable(chip, itr_num); 249f932e355SEtienne Carriere } 250f932e355SEtienne Carriere 251f932e355SEtienne Carriere /* 252f932e355SEtienne Carriere * interrupt_disable() - Disable an interrupt 253f932e355SEtienne Carriere * @chip Interrupt controller 254f932e355SEtienne Carriere * @itr_num Interrupt number 255f932e355SEtienne Carriere */ 256f932e355SEtienne Carriere static inline void interrupt_disable(struct itr_chip *chip, size_t itr_num) 257f932e355SEtienne Carriere { 258f932e355SEtienne Carriere chip->ops->disable(chip, itr_num); 259f932e355SEtienne Carriere } 260f932e355SEtienne Carriere 261f932e355SEtienne Carriere /* 262*b2d6db21SEtienne Carriere * interrupt_can_raise_pi() - Return whether controller embeds raise_pi 263*b2d6db21SEtienne Carriere * @chip Interrupt controller 264*b2d6db21SEtienne Carriere */ 265*b2d6db21SEtienne Carriere static inline bool interrupt_can_raise_pi(struct itr_chip *chip) 266*b2d6db21SEtienne Carriere { 267*b2d6db21SEtienne Carriere return chip->ops->raise_pi; 268*b2d6db21SEtienne Carriere } 269*b2d6db21SEtienne Carriere 270*b2d6db21SEtienne Carriere /* 271*b2d6db21SEtienne Carriere * interrupt_can_raise_sgi() - Return whether controller embeds raise_sgi 272*b2d6db21SEtienne Carriere * @chip Interrupt controller 273*b2d6db21SEtienne Carriere */ 274*b2d6db21SEtienne Carriere static inline bool interrupt_can_raise_sgi(struct itr_chip *chip) 275*b2d6db21SEtienne Carriere { 276*b2d6db21SEtienne Carriere return chip->ops->raise_sgi; 277*b2d6db21SEtienne Carriere } 278*b2d6db21SEtienne Carriere 279*b2d6db21SEtienne Carriere /* 280*b2d6db21SEtienne Carriere * interrupt_can_set_affinity() - Return whether controller embeds set_affinity 281*b2d6db21SEtienne Carriere * @chip Interrupt controller 282*b2d6db21SEtienne Carriere */ 283*b2d6db21SEtienne Carriere static inline bool interrupt_can_set_affinity(struct itr_chip *chip) 284*b2d6db21SEtienne Carriere { 285*b2d6db21SEtienne Carriere return chip->ops->set_affinity; 286*b2d6db21SEtienne Carriere } 287*b2d6db21SEtienne Carriere 288*b2d6db21SEtienne Carriere /* 289*b2d6db21SEtienne Carriere * interrupt_raise_pi() - Raise a peripheral interrupt of a controller 290*b2d6db21SEtienne Carriere * @chip Interrupt controller 291*b2d6db21SEtienne Carriere * @itr_num Interrupt number to raise 292*b2d6db21SEtienne Carriere */ 293*b2d6db21SEtienne Carriere static inline void interrupt_raise_pi(struct itr_chip *chip, size_t itr_num) 294*b2d6db21SEtienne Carriere { 295*b2d6db21SEtienne Carriere assert(interrupt_can_raise_pi(chip)); 296*b2d6db21SEtienne Carriere chip->ops->raise_pi(chip, itr_num); 297*b2d6db21SEtienne Carriere } 298*b2d6db21SEtienne Carriere 299*b2d6db21SEtienne Carriere /* 300*b2d6db21SEtienne Carriere * interrupt_raise_sgi() - Raise a software generiated interrupt of a controller 301*b2d6db21SEtienne Carriere * @chip Interrupt controller 302*b2d6db21SEtienne Carriere * @itr_num Interrupt number to raise 303*b2d6db21SEtienne Carriere * @cpu_mask Mask of the CPUs targeted by the interrupt 304*b2d6db21SEtienne Carriere */ 305*b2d6db21SEtienne Carriere static inline void interrupt_raise_sgi(struct itr_chip *chip, size_t itr_num, 306*b2d6db21SEtienne Carriere uint8_t cpu_mask) 307*b2d6db21SEtienne Carriere { 308*b2d6db21SEtienne Carriere assert(interrupt_can_raise_sgi(chip)); 309*b2d6db21SEtienne Carriere chip->ops->raise_sgi(chip, itr_num, cpu_mask); 310*b2d6db21SEtienne Carriere } 311*b2d6db21SEtienne Carriere 312*b2d6db21SEtienne Carriere /* 313*b2d6db21SEtienne Carriere * interrupt_set_affinity() - Set CPU affinity for a controller interrupt 314*b2d6db21SEtienne Carriere * @chip Interrupt controller 315*b2d6db21SEtienne Carriere * @itr_num Interrupt number to raise 316*b2d6db21SEtienne Carriere * @cpu_mask Mask of the CPUs targeted by the interrupt 317*b2d6db21SEtienne Carriere */ 318*b2d6db21SEtienne Carriere static inline void interrupt_set_affinity(struct itr_chip *chip, size_t itr_num, 319*b2d6db21SEtienne Carriere uint8_t cpu_mask) 320*b2d6db21SEtienne Carriere { 321*b2d6db21SEtienne Carriere assert(interrupt_can_set_affinity(chip)); 322*b2d6db21SEtienne Carriere chip->ops->set_affinity(chip, itr_num, cpu_mask); 323*b2d6db21SEtienne Carriere } 324*b2d6db21SEtienne Carriere 325*b2d6db21SEtienne Carriere /* 326f932e355SEtienne Carriere * interrupt_configure() - Configure an interrupt in an interrupt controller 327f932e355SEtienne Carriere * @chip Interrupt controller 328f932e355SEtienne Carriere * @itr_num Interrupt number 329f932e355SEtienne Carriere * @type Interrupt trigger type (IRQ_TYPE_* defines) or IRQ_TYPE_NONE 330f932e355SEtienne Carriere * @prio Interrupt priority or 0 331f932e355SEtienne Carriere * 332f932e355SEtienne Carriere * Interrupt consumers that get their interrupt from the DT do not need to 333f932e355SEtienne Carriere * call interrupt_configure() since the interrupt configuration has already 334f932e355SEtienne Carriere * been done by interrupt controller based on the DT bidings. 335f932e355SEtienne Carriere */ 336f932e355SEtienne Carriere TEE_Result interrupt_configure(struct itr_chip *chip, size_t itr_num, 337f932e355SEtienne Carriere uint32_t type, uint32_t prio); 338f932e355SEtienne Carriere 339f932e355SEtienne Carriere /* 340f932e355SEtienne Carriere * interrupt_add_and_configure_handler() - Register and configure a handler 341f932e355SEtienne Carriere * @hdl Interrupt handler to register 342f932e355SEtienne Carriere * @type Interrupt trigger type (IRQ_TYPE_* defines) or IRQ_TYPE_NONE 343f932e355SEtienne Carriere * @prio Interrupt priority or 0 344f932e355SEtienne Carriere */ 345f932e355SEtienne Carriere TEE_Result interrupt_add_configure_handler(struct itr_handler *hdl, 346f932e355SEtienne Carriere uint32_t type, uint32_t prio); 347f932e355SEtienne Carriere 348f932e355SEtienne Carriere /* 349f932e355SEtienne Carriere * interrupt_add_handler() - Register an interrupt handler 350f932e355SEtienne Carriere * @hdl Interrupt handler to register 351f932e355SEtienne Carriere * 352f932e355SEtienne Carriere * This helper function assumes interrupt type is set to IRQ_TYPE_NONE 353f932e355SEtienne Carriere * and interrupt priority to 0. 354f932e355SEtienne Carriere */ 355f932e355SEtienne Carriere static inline TEE_Result interrupt_add_handler(struct itr_handler *hdl) 356f932e355SEtienne Carriere { 357f932e355SEtienne Carriere return interrupt_add_configure_handler(hdl, IRQ_TYPE_NONE, 0); 358f932e355SEtienne Carriere } 359f932e355SEtienne Carriere 360f932e355SEtienne Carriere /* 361f932e355SEtienne Carriere * interrupt_add_handler_with_chip() - Register an interrupt handler providing 362f932e355SEtienne Carriere * the interrupt chip reference in specific argument @chip. 363f932e355SEtienne Carriere * @chip Interrupt controller 364f932e355SEtienne Carriere * @h Interrupt handler to register 365f932e355SEtienne Carriere */ 366f932e355SEtienne Carriere static inline TEE_Result interrupt_add_handler_with_chip(struct itr_chip *chip, 367f932e355SEtienne Carriere struct itr_handler *h) 368f932e355SEtienne Carriere { 369f932e355SEtienne Carriere h->chip = chip; 370f932e355SEtienne Carriere return interrupt_add_handler(h); 371f932e355SEtienne Carriere } 372f932e355SEtienne Carriere 373f932e355SEtienne Carriere /* 374f932e355SEtienne Carriere * interrupt_remove_handler() - Remove a registered interrupt handler 375f932e355SEtienne Carriere * @hdl Interrupt handler to remove 376f932e355SEtienne Carriere * 377f932e355SEtienne Carriere * This function is the counterpart of interrupt_add_handler(). 378f932e355SEtienne Carriere * This function may panic on non-NULL invalid @hdl reference. 379f932e355SEtienne Carriere */ 380f932e355SEtienne Carriere void interrupt_remove_handler(struct itr_handler *hdl); 381f932e355SEtienne Carriere 382f932e355SEtienne Carriere /* 3831b5c7ca4SEtienne Carriere * interrupt_alloc_add_conf_handler() - Allocate, configure, register a handler 3841b5c7ca4SEtienne Carriere * @chip Interrupt controller 3851b5c7ca4SEtienne Carriere * @itr_num Interrupt number 3861b5c7ca4SEtienne Carriere * @handler Interrupt handler to register 3871b5c7ca4SEtienne Carriere * @flags Bitmask flag ITRF_* 3881b5c7ca4SEtienne Carriere * @data Private data reference passed to @handler 3891b5c7ca4SEtienne Carriere * @type Interrupt trigger type (IRQ_TYPE_* defines) or IRQ_TYPE_NONE 3901b5c7ca4SEtienne Carriere * @prio Interrupt priority or 0 3911b5c7ca4SEtienne Carriere * @out_hdl NULL or output pointer to allocated struct itr_handler 3921b5c7ca4SEtienne Carriere */ 3931b5c7ca4SEtienne Carriere TEE_Result interrupt_alloc_add_conf_handler(struct itr_chip *chip, 3941b5c7ca4SEtienne Carriere size_t it_num, 3951b5c7ca4SEtienne Carriere itr_handler_t handler, 3961b5c7ca4SEtienne Carriere uint32_t flags, void *data, 3971b5c7ca4SEtienne Carriere uint32_t type, uint32_t prio, 3981b5c7ca4SEtienne Carriere struct itr_handler **out_hdl); 3991b5c7ca4SEtienne Carriere 4001b5c7ca4SEtienne Carriere /* 401f932e355SEtienne Carriere * interrupt_alloc_add_handler() - Allocate and register an interrupt handler 402f932e355SEtienne Carriere * @chip Interrupt controller 403f932e355SEtienne Carriere * @itr_num Interrupt number 404f932e355SEtienne Carriere * @handler Interrupt handler to register 405f932e355SEtienne Carriere * @flags Bitmask flag ITRF_* 406f932e355SEtienne Carriere * @data Private data reference passed to @handler 407f932e355SEtienne Carriere * @out_hdl NULL or output pointer to allocated struct itr_handler 408f932e355SEtienne Carriere */ 4091b5c7ca4SEtienne Carriere static inline TEE_Result interrupt_alloc_add_handler(struct itr_chip *chip, 4101b5c7ca4SEtienne Carriere size_t it_num, 4111b5c7ca4SEtienne Carriere itr_handler_t handler, 4121b5c7ca4SEtienne Carriere uint32_t flags, 413f932e355SEtienne Carriere void *data, 4141b5c7ca4SEtienne Carriere struct itr_handler **hdl) 4151b5c7ca4SEtienne Carriere { 4161b5c7ca4SEtienne Carriere return interrupt_alloc_add_conf_handler(chip, it_num, handler, flags, 4171b5c7ca4SEtienne Carriere data, IRQ_TYPE_NONE, 0, hdl); 4181b5c7ca4SEtienne Carriere } 419f932e355SEtienne Carriere 420f932e355SEtienne Carriere /* 421f932e355SEtienne Carriere * interrupt_remove_free_handler() - Remove/free a registered interrupt handler 422f932e355SEtienne Carriere * @hdl Interrupt handler to remove and free 423f932e355SEtienne Carriere * 4241b5c7ca4SEtienne Carriere * This function is the counterpart of interrupt_alloc_add_handler() 4251b5c7ca4SEtienne Carriere * and interrupt_alloc_add_conf_handler(). 426f932e355SEtienne Carriere * This function may panic on non-NULL invalid @hdl reference. 427f932e355SEtienne Carriere */ 428f932e355SEtienne Carriere void interrupt_remove_free_handler(struct itr_handler *hdl); 4297315b7b4SJens Wiklander #endif /*__KERNEL_INTERRUPT_H*/ 430