1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2016, Linaro Limited 4 */ 5 6 #include <kernel/interrupt.h> 7 #include <trace.h> 8 9 /* 10 * NOTE! 11 * 12 * We're assuming that there's no concurrent use of this interface, except 13 * delivery of interrupts in parallel. Synchronization will be needed when 14 * we begin to modify settings after boot initialization. 15 */ 16 17 static struct itr_chip *itr_chip; 18 static SLIST_HEAD(, itr_handler) handlers = SLIST_HEAD_INITIALIZER(handlers); 19 20 void itr_init(struct itr_chip *chip) 21 { 22 itr_chip = chip; 23 } 24 25 static struct itr_handler *find_handler(size_t it) 26 { 27 struct itr_handler *h; 28 29 SLIST_FOREACH(h, &handlers, link) 30 if (h->it == it) 31 return h; 32 return NULL; 33 } 34 35 void itr_handle(size_t it) 36 { 37 struct itr_handler *h = find_handler(it); 38 39 if (!h) { 40 EMSG("Disabling unhandled interrupt %zu", it); 41 itr_chip->ops->disable(itr_chip, it); 42 return; 43 } 44 45 if (h->handler(h) != ITRR_HANDLED) { 46 EMSG("Disabling interrupt %zu not handled by handler", it); 47 itr_chip->ops->disable(itr_chip, it); 48 } 49 } 50 51 void itr_add(struct itr_handler *h) 52 { 53 itr_chip->ops->add(itr_chip, h->it, h->flags); 54 SLIST_INSERT_HEAD(&handlers, h, link); 55 } 56 57 void itr_enable(size_t it) 58 { 59 itr_chip->ops->enable(itr_chip, it); 60 } 61 62 void itr_disable(size_t it) 63 { 64 itr_chip->ops->disable(itr_chip, it); 65 } 66 67 void itr_raise_pi(size_t it) 68 { 69 itr_chip->ops->raise_pi(itr_chip, it); 70 } 71 72 void itr_raise_sgi(size_t it, uint8_t cpu_mask) 73 { 74 itr_chip->ops->raise_sgi(itr_chip, it, cpu_mask); 75 } 76 77 void itr_set_affinity(size_t it, uint8_t cpu_mask) 78 { 79 itr_chip->ops->set_affinity(itr_chip, it, cpu_mask); 80 } 81