]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.29/genirq-generic_chip-add-irq_unmap-callback.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.29 / genirq-generic_chip-add-irq_unmap-callback.patch
1 From ee26c013cdee0b947e29d6cadfb9ff3341c69ff9 Mon Sep 17 00:00:00 2001
2 From: Sebastian Frias <sf84@laposte.net>
3 Date: Mon, 1 Aug 2016 16:27:38 +0200
4 Subject: genirq/generic_chip: Add irq_unmap callback
5
6 From: Sebastian Frias <sf84@laposte.net>
7
8 commit ee26c013cdee0b947e29d6cadfb9ff3341c69ff9 upstream.
9
10 Without this patch irq_domain_disassociate() cannot properly release the
11 interrupt. In fact, irq_map_generic_chip() checks a bit on 'gc->installed'
12 but said bit is never cleared, only set.
13
14 Commit 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support")
15 added irq_map_generic_chip() function and also stated "This lacks a removal
16 function for now".
17
18 This commit provides an implementation of an unmap function that can be
19 called by irq_domain_disassociate().
20
21 [ tglx: Made the function static and removed the export as we have neither
22 a prototype nor a modular user. ]
23
24 Fixes: 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support")
25 Signed-off-by: Sebastian Frias <sf84@laposte.net>
26 Cc: Marc Zyngier <marc.zyngier@arm.com>
27 Cc: Mason <slash.tmp@free.fr>
28 Cc: Jason Cooper <jason@lakedaemon.net>
29 Link: http://lkml.kernel.org/r/579F5C5A.2070507@laposte.net
30 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
31 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
32
33 ---
34 kernel/irq/generic-chip.c | 21 +++++++++++++++++++++
35 1 file changed, 21 insertions(+)
36
37 --- a/kernel/irq/generic-chip.c
38 +++ b/kernel/irq/generic-chip.c
39 @@ -411,8 +411,29 @@ int irq_map_generic_chip(struct irq_doma
40 }
41 EXPORT_SYMBOL_GPL(irq_map_generic_chip);
42
43 +static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq)
44 +{
45 + struct irq_data *data = irq_domain_get_irq_data(d, virq);
46 + struct irq_domain_chip_generic *dgc = d->gc;
47 + unsigned int hw_irq = data->hwirq;
48 + struct irq_chip_generic *gc;
49 + int irq_idx;
50 +
51 + gc = irq_get_domain_generic_chip(d, hw_irq);
52 + if (!gc)
53 + return;
54 +
55 + irq_idx = hw_irq % dgc->irqs_per_chip;
56 +
57 + clear_bit(irq_idx, &gc->installed);
58 + irq_domain_set_info(d, virq, hw_irq, &no_irq_chip, NULL, NULL, NULL,
59 + NULL);
60 +
61 +}
62 +
63 struct irq_domain_ops irq_generic_chip_ops = {
64 .map = irq_map_generic_chip,
65 + .unmap = irq_unmap_generic_chip,
66 .xlate = irq_domain_xlate_onetwocell,
67 };
68 EXPORT_SYMBOL_GPL(irq_generic_chip_ops);