/* * SPDX-License-Identifier: GPL-2.0 * * Copyright (C) 2020 Philippe Gerum */ #ifndef _COBALT_KERNEL_DOVETAIL_SIRQ_H #define _COBALT_KERNEL_DOVETAIL_SIRQ_H #include #include /* * Wrappers to create "synthetic IRQs" the Dovetail way. Those * interrupt channels can only be trigged by software, in order to run * a handler on the in-band execution stage. */ static inline int pipeline_create_inband_sirq(irqreturn_t (*handler)(int irq, void *dev_id)) { /* * Allocate an IRQ from the synthetic interrupt domain then * trap it to @handler, to be fired from the in-band stage. */ int sirq, ret; sirq = irq_create_direct_mapping(synthetic_irq_domain); if (sirq == 0) return -EAGAIN; ret = __request_percpu_irq(sirq, handler, IRQF_NO_THREAD, "Inband sirq", &cobalt_machine_cpudata); if (ret) { irq_dispose_mapping(sirq); return ret; } return sirq; } static inline void pipeline_delete_inband_sirq(int sirq) { /* * Free the synthetic IRQ then deallocate it to its * originating domain. */ free_percpu_irq(sirq, &cobalt_machine_cpudata); irq_dispose_mapping(sirq); } static inline void pipeline_post_sirq(int sirq) { /* Trigger the synthetic IRQ */ irq_post_inband(sirq); } #endif /* !_COBALT_KERNEL_DOVETAIL_SIRQ_H */