Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2018, Arm Limited. All rights reserved. |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #ifndef __IRQ_H__ |
| 8 | #define __IRQ_H__ |
| 9 | |
Ambroise Vincent | 602b7f5 | 2019-02-11 14:13:43 +0000 | [diff] [blame] | 10 | #include <cdefs.h> |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 11 | #include <platform_def.h> /* For CACHE_WRITEBACK_GRANULE */ |
| 12 | #include <stdint.h> |
| 13 | |
| 14 | /* |
| 15 | * SGI sent by the timer management framework to notify CPUs when the system |
| 16 | * timer fires off |
| 17 | */ |
| 18 | #define IRQ_WAKE_SGI IRQ_NS_SGI_7 |
| 19 | |
| 20 | #ifndef __ASSEMBLY__ |
| 21 | |
| 22 | /* Prototype of a handler function for an IRQ */ |
| 23 | typedef int (*irq_handler_t)(void *data); |
| 24 | |
| 25 | /* Keep track of the IRQ handler registered for a given SPI */ |
| 26 | typedef struct { |
| 27 | irq_handler_t handler; |
| 28 | } spi_desc; |
| 29 | |
| 30 | /* Keep track of the IRQ handler registered for a spurious interrupt */ |
| 31 | typedef irq_handler_t spurious_desc; |
| 32 | |
| 33 | /* |
| 34 | * PPIs and SGIs are interrupts that are private to a GIC CPU interface. These |
| 35 | * interrupts are banked in the GIC Distributor. Therefore, each CPU can |
| 36 | * set up a different IRQ handler for a given PPI/SGI. |
| 37 | * |
| 38 | * So we define a data structure representing an IRQ handler aligned on the |
| 39 | * size of a cache line. This guarantees that in an array of these, each element |
| 40 | * is loaded in a separate cache line. This allows efficient concurrent |
| 41 | * manipulation of these elements on different CPUs. |
| 42 | */ |
| 43 | typedef struct { |
| 44 | irq_handler_t handler; |
| 45 | } __aligned(CACHE_WRITEBACK_GRANULE) irq_handler_banked_t; |
| 46 | |
| 47 | typedef irq_handler_banked_t ppi_desc; |
| 48 | typedef irq_handler_banked_t sgi_desc; |
| 49 | |
| 50 | void tftf_irq_setup(void); |
| 51 | |
| 52 | /* |
| 53 | * Generic handler called upon reception of an IRQ. |
| 54 | * |
| 55 | * This function acknowledges the interrupt, calls the user-defined handler |
| 56 | * if one has been registered then marks the processing of the interrupt as |
| 57 | * complete. |
| 58 | */ |
| 59 | int tftf_irq_handler_dispatcher(void); |
| 60 | |
| 61 | /* |
| 62 | * Enable interrupt #irq_num for the calling core. |
| 63 | */ |
| 64 | void tftf_irq_enable(unsigned int irq_num, uint8_t irq_priority); |
| 65 | |
| 66 | /* |
| 67 | * Disable interrupt #irq_num for the calling core. |
| 68 | */ |
| 69 | void tftf_irq_disable(unsigned int irq_num); |
| 70 | |
| 71 | /* |
| 72 | * Register an interrupt handler for a given interrupt number. |
| 73 | * Will fail if there is already an interrupt handler registered for the same |
| 74 | * interrupt. |
| 75 | * |
| 76 | * Return 0 on success, a negative value otherwise. |
| 77 | */ |
| 78 | int tftf_irq_register_handler(unsigned int num, irq_handler_t irq_handler); |
| 79 | |
| 80 | /* |
| 81 | * Unregister an interrupt handler for a given interrupt number. |
| 82 | * Will fail if there is no interrupt handler registered for that interrupt. |
| 83 | * |
| 84 | * Return 0 on success, a negative value otherwise. |
| 85 | */ |
| 86 | int tftf_irq_unregister_handler(unsigned int irq_num); |
| 87 | |
| 88 | #endif /* __ASSEMBLY__ */ |
| 89 | |
| 90 | #endif /* __IRQ_H__ */ |