Commit 966dc736b819999cd2d3a6408d47d33b579f7d56
1 parent
af80b0fed6
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
genirq: Generic chip: Cache per irq bit mask
Cache the per irq bit mask instead of recalculating it over and over. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Cc: Andrew Lunn <andrew@lunn.ch> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Jean-Francois Moine <moinejf@free.fr> Cc: devicetree-discuss@lists.ozlabs.org Cc: Rob Herring <rob.herring@calxeda.com> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Cc: Gregory Clement <gregory.clement@free-electrons.com> Cc: Gerlando Falauto <gerlando.falauto@keymile.com> Cc: Rob Landley <rob@landley.net> Acked-by: Grant Likely <grant.likely@linaro.org> Cc: Maxime Ripard <maxime.ripard@free-electrons.com> Cc: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> Cc: linux-arm-kernel@lists.infradead.org Cc: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Link: http://lkml.kernel.org/r/20130506142539.227119865@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Showing 2 changed files with 18 additions and 9 deletions Side-by-side Diff
include/linux/irq.h
... | ... | @@ -119,6 +119,7 @@ |
119 | 119 | |
120 | 120 | /** |
121 | 121 | * struct irq_data - per irq and irq chip data passed down to chip functions |
122 | + * @mask: precomputed bitmask for accessing the chip registers | |
122 | 123 | * @irq: interrupt number |
123 | 124 | * @hwirq: hardware interrupt number, local to the interrupt domain |
124 | 125 | * @node: node index useful for balancing |
... | ... | @@ -138,6 +139,7 @@ |
138 | 139 | * irq_data. |
139 | 140 | */ |
140 | 141 | struct irq_data { |
142 | + u32 mask; | |
141 | 143 | unsigned int irq; |
142 | 144 | unsigned long hwirq; |
143 | 145 | unsigned int node; |
144 | 146 | |
... | ... | @@ -705,11 +707,13 @@ |
705 | 707 | * irq chips which need to call irq_set_wake() on |
706 | 708 | * the parent irq. Usually GPIO implementations |
707 | 709 | * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private |
710 | + * @IRQ_GC_NO_MASK: Do not calculate irq_data->mask | |
708 | 711 | */ |
709 | 712 | enum irq_gc_flags { |
710 | 713 | IRQ_GC_INIT_MASK_CACHE = 1 << 0, |
711 | 714 | IRQ_GC_INIT_NESTED_LOCK = 1 << 1, |
712 | 715 | IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2, |
716 | + IRQ_GC_NO_MASK = 1 << 3, | |
713 | 717 | }; |
714 | 718 | |
715 | 719 | /* Generic chip callback functions */ |
kernel/irq/generic-chip.c
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | { |
36 | 36 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
37 | 37 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
38 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
38 | + u32 mask = d->mask; | |
39 | 39 | |
40 | 40 | irq_gc_lock(gc); |
41 | 41 | irq_reg_writel(mask, gc->reg_base + ct->regs.disable); |
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 | { |
55 | 55 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
56 | 56 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
57 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
57 | + u32 mask = d->mask; | |
58 | 58 | |
59 | 59 | irq_gc_lock(gc); |
60 | 60 | *ct->mask_cache |= mask; |
... | ... | @@ -73,7 +73,7 @@ |
73 | 73 | { |
74 | 74 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
75 | 75 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
76 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
76 | + u32 mask = d->mask; | |
77 | 77 | |
78 | 78 | irq_gc_lock(gc); |
79 | 79 | *ct->mask_cache &= ~mask; |
... | ... | @@ -92,7 +92,7 @@ |
92 | 92 | { |
93 | 93 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
94 | 94 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
95 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
95 | + u32 mask = d->mask; | |
96 | 96 | |
97 | 97 | irq_gc_lock(gc); |
98 | 98 | irq_reg_writel(mask, gc->reg_base + ct->regs.enable); |
... | ... | @@ -108,7 +108,7 @@ |
108 | 108 | { |
109 | 109 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
110 | 110 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
111 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
111 | + u32 mask = d->mask; | |
112 | 112 | |
113 | 113 | irq_gc_lock(gc); |
114 | 114 | irq_reg_writel(mask, gc->reg_base + ct->regs.ack); |
... | ... | @@ -123,7 +123,7 @@ |
123 | 123 | { |
124 | 124 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
125 | 125 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
126 | - u32 mask = ~(1 << (d->irq - gc->irq_base)); | |
126 | + u32 mask = ~d->mask; | |
127 | 127 | |
128 | 128 | irq_gc_lock(gc); |
129 | 129 | irq_reg_writel(mask, gc->reg_base + ct->regs.ack); |
... | ... | @@ -138,7 +138,7 @@ |
138 | 138 | { |
139 | 139 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
140 | 140 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
141 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
141 | + u32 mask = d->mask; | |
142 | 142 | |
143 | 143 | irq_gc_lock(gc); |
144 | 144 | irq_reg_writel(mask, gc->reg_base + ct->regs.mask); |
... | ... | @@ -154,7 +154,7 @@ |
154 | 154 | { |
155 | 155 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
156 | 156 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
157 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
157 | + u32 mask = d->mask; | |
158 | 158 | |
159 | 159 | irq_gc_lock(gc); |
160 | 160 | irq_reg_writel(mask, gc->reg_base + ct->regs.eoi); |
... | ... | @@ -172,7 +172,7 @@ |
172 | 172 | int irq_gc_set_wake(struct irq_data *d, unsigned int on) |
173 | 173 | { |
174 | 174 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
175 | - u32 mask = 1 << (d->irq - gc->irq_base); | |
175 | + u32 mask = d->mask; | |
176 | 176 | |
177 | 177 | if (!(mask & gc->wake_enabled)) |
178 | 178 | return -EINVAL; |
... | ... | @@ -264,6 +264,11 @@ |
264 | 264 | if (flags & IRQ_GC_INIT_NESTED_LOCK) |
265 | 265 | irq_set_lockdep_class(i, &irq_nested_lock_class); |
266 | 266 | |
267 | + if (!(flags & IRQ_GC_NO_MASK)) { | |
268 | + struct irq_data *d = irq_get_irq_data(i); | |
269 | + | |
270 | + d->mask = 1 << (i - gc->irq_base); | |
271 | + } | |
267 | 272 | irq_set_chip_and_handler(i, &ct->chip, ct->handler); |
268 | 273 | irq_set_chip_data(i, gc); |
269 | 274 | irq_modify_status(i, clr, set); |