This is a note to let you know that I've just added the patch titled
genirq: Track whether the trigger type has been set
to the 3.18-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: genirq-track-whether-the-trigger-type-has-been-set.patch and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From 4f8413a3a799c958f7a10a6310a451e6b8aef5ad Mon Sep 17 00:00:00 2001
From: Marc Zyngier marc.zyngier@arm.com Date: Thu, 9 Nov 2017 14:17:59 +0000 Subject: genirq: Track whether the trigger type has been set
From: Marc Zyngier marc.zyngier@arm.com
commit 4f8413a3a799c958f7a10a6310a451e6b8aef5ad upstream.
When requesting a shared interrupt, we assume that the firmware support code (DT or ACPI) has called irqd_set_trigger_type already, so that we can retrieve it and check that the requester is being reasonnable.
Unfortunately, we still have non-DT, non-ACPI systems around, and these guys won't call irqd_set_trigger_type before requesting the interrupt. The consequence is that we fail the request that would have worked before.
We can either chase all these use cases (boring), or address it in core code (easier). Let's have a per-irq_desc flag that indicates whether irqd_set_trigger_type has been called, and let's just check it when checking for a shared interrupt. If it hasn't been set, just take whatever the interrupt requester asks.
Fixes: 382bd4de6182 ("genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs") Cc: stable@vger.kernel.org Reported-and-tested-by: Petr Cvek petrcvekcz@gmail.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/irq.h | 11 ++++++++++- kernel/irq/manage.c | 13 ++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-)
--- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -175,6 +175,7 @@ struct irq_data { * IRQD_IRQ_MASKED - Masked state of the interrupt * IRQD_IRQ_INPROGRESS - In progress state of the interrupt * IRQD_WAKEUP_ARMED - Wakeup mode armed + * IRQD_DEFAULT_TRIGGER_SET - Expected trigger already been set */ enum { IRQD_TRIGGER_MASK = 0xf, @@ -189,6 +190,7 @@ enum { IRQD_IRQ_MASKED = (1 << 17), IRQD_IRQ_INPROGRESS = (1 << 18), IRQD_WAKEUP_ARMED = (1 << 19), + IRQD_DEFAULT_TRIGGER_SET = (1 << 25), };
static inline bool irqd_is_setaffinity_pending(struct irq_data *d) @@ -216,18 +218,25 @@ static inline void irqd_mark_affinity_wa d->state_use_accessors |= IRQD_AFFINITY_SET; }
+static inline bool irqd_trigger_type_was_set(struct irq_data *d) +{ + return d->state_use_accessors & IRQD_DEFAULT_TRIGGER_SET; +} + static inline u32 irqd_get_trigger_type(struct irq_data *d) { return d->state_use_accessors & IRQD_TRIGGER_MASK; }
/* - * Must only be called inside irq_chip.irq_set_type() functions. + * Must only be called inside irq_chip.irq_set_type() functions or + * from the DT/ACPI setup code. */ static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) { d->state_use_accessors &= ~IRQD_TRIGGER_MASK; d->state_use_accessors |= type & IRQD_TRIGGER_MASK; + d->state_use_accessors |= IRQD_DEFAULT_TRIGGER_SET; }
static inline bool irqd_is_level_type(struct irq_data *d) --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1058,7 +1058,18 @@ __setup_irq(unsigned int irq, struct irq * set the trigger type must match. Also all must * agree on ONESHOT. */ - unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data); + unsigned int oldtype; + + /* + * If nobody did set the configuration before, inherit + * the one provided by the requester. + */ + if (irqd_trigger_type_was_set(&desc->irq_data)) { + oldtype = irqd_get_trigger_type(&desc->irq_data); + } else { + oldtype = new->flags & IRQF_TRIGGER_MASK; + irqd_set_trigger_type(&desc->irq_data, oldtype); + }
if (!((old->flags & new->flags) & IRQF_SHARED) || (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
Patches currently in stable-queue which might be from marc.zyngier@arm.com are
queue-3.18/genirq-track-whether-the-trigger-type-has-been-set.patch
linux-stable-mirror@lists.linaro.org