We need to overload these services for irqchips that cannot be hardened to work from arbitrary contexts.
Signed-off-by: Jan Kiszka <[email protected]> --- I'm still lagging behind with making use of this for MSI masking or refactoring the Xenomai HAL to use it, but it's a start. include/linux/ipipe.h | 22 ++++++++++++++++++++++ include/linux/ipipe_base.h | 1 + include/linux/irq.h | 2 ++ kernel/ipipe/core.c | 6 ++++++ 4 files changed, 31 insertions(+), 0 deletions(-) diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h index 854f132..da2bd68 100644 --- a/include/linux/ipipe.h +++ b/include/linux/ipipe.h @@ -28,6 +28,7 @@ #include <linux/mutex.h> #include <linux/linkage.h> #include <linux/ipipe_base.h> +#include <linux/irq.h> #include <asm/ipipe.h> #include <asm/bug.h> @@ -440,6 +441,27 @@ int ipipe_control_irq(struct ipipe_domain *ipd, unsigned clrmask, unsigned setmask); +static inline void ipipe_irq_chip_mask(unsigned int irq, struct irq_desc *desc) +{ + desc->ipipe_mask(irq); +} + +static inline void +ipipe_irq_chip_unmask(unsigned int irq, struct irq_desc *desc) +{ + desc->ipipe_unmask(irq); +} + +void __ipipe_irq_chip_nop(unsigned int irq); + +#ifndef HAVE_IPIPE_IRQ_DESC_SET_HANDLERS +static inline void ipipe_irq_desc_set_handlers(struct irq_desc *desc) +{ + desc->ipipe_mask = desc->chip->mask ? : __ipipe_irq_chip_nop; + desc->ipipe_unmask = desc->chip->unmask ? : __ipipe_irq_chip_nop; +} +#endif + unsigned ipipe_alloc_virq(void); int ipipe_free_virq(unsigned virq); diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h index 3f43ba5..7152485 100644 --- a/include/linux/ipipe_base.h +++ b/include/linux/ipipe_base.h @@ -110,6 +110,7 @@ static inline void ipipe_check_context(struct ipipe_domain *border_ipd) { } #define __IPIPE_FEATURE_PREPARE_PANIC 1 #define __IPIPE_FEATURE_ROOT_PREEMPT_NOTIFIER 1 #define __IPIPE_FEATURE_CONTROL_IRQ 1 +#define __IPIPE_FEATURE_IRQ_CHIP_MASK 1 #else /* !CONFIG_IPIPE */ diff --git a/include/linux/irq.h b/include/linux/irq.h index 630e995..a6969d6 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -181,6 +181,8 @@ struct irq_desc { struct irq_desc *desc); void (*ipipe_end)(unsigned int irq, struct irq_desc *desc); + void (*ipipe_mask)(unsigned int irq); + void (*ipipe_unmask)(unsigned int irq); #endif /* CONFIG_IPIPE */ unsigned int irq; struct timer_rand_state *timer_rand_state; diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c index 9d025b2..756ad02 100644 --- a/kernel/ipipe/core.c +++ b/kernel/ipipe/core.c @@ -889,6 +889,10 @@ unsigned ipipe_alloc_virq(void) return irq; } +void __ipipe_irq_chip_nop(unsigned int irq) +{ +} + /* * ipipe_virtualize_irq() -- Set a per-domain pipelined interrupt * handler. @@ -981,6 +985,8 @@ int ipipe_virtualize_irq(struct ipipe_domain *ipd, if (desc == NULL) goto unlock_and_exit; + ipipe_irq_desc_set_handlers(desc); + if (irq < NR_IRQS && !ipipe_virtual_irq_p(irq)) { __ipipe_enable_irqdesc(ipd, irq); /* _______________________________________________ Adeos-main mailing list [email protected] https://mail.gna.org/listinfo/adeos-main
