aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-05-06 10:30:22 -0400
committerThomas Gleixner <tglx@linutronix.de>2013-05-29 04:57:10 -0400
commit966dc736b819999cd2d3a6408d47d33b579f7d56 (patch)
tree49935202236e9d0b66cf7f9330d8c99eecc89b51
parentaf80b0fed67261dcba2ce2406db1d553d07cbe75 (diff)
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>
-rw-r--r--include/linux/irq.h4
-rw-r--r--kernel/irq/generic-chip.c23
2 files changed, 18 insertions, 9 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 7f1f0157fd00..d5fc7f5a49b8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -119,6 +119,7 @@ struct irq_domain;
119 119
120/** 120/**
121 * struct irq_data - per irq and irq chip data passed down to chip functions 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 * @irq: interrupt number 123 * @irq: interrupt number
123 * @hwirq: hardware interrupt number, local to the interrupt domain 124 * @hwirq: hardware interrupt number, local to the interrupt domain
124 * @node: node index useful for balancing 125 * @node: node index useful for balancing
@@ -138,6 +139,7 @@ struct irq_domain;
138 * irq_data. 139 * irq_data.
139 */ 140 */
140struct irq_data { 141struct irq_data {
142 u32 mask;
141 unsigned int irq; 143 unsigned int irq;
142 unsigned long hwirq; 144 unsigned long hwirq;
143 unsigned int node; 145 unsigned int node;
@@ -705,11 +707,13 @@ struct irq_chip_generic {
705 * irq chips which need to call irq_set_wake() on 707 * irq chips which need to call irq_set_wake() on
706 * the parent irq. Usually GPIO implementations 708 * the parent irq. Usually GPIO implementations
707 * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private 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 */
709enum irq_gc_flags { 712enum irq_gc_flags {
710 IRQ_GC_INIT_MASK_CACHE = 1 << 0, 713 IRQ_GC_INIT_MASK_CACHE = 1 << 0,
711 IRQ_GC_INIT_NESTED_LOCK = 1 << 1, 714 IRQ_GC_INIT_NESTED_LOCK = 1 << 1,
712 IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2, 715 IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2,
716 IRQ_GC_NO_MASK = 1 << 3,
713}; 717};
714 718
715/* Generic chip callback functions */ 719/* Generic chip callback functions */
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index da2a94191fc5..957155cebbac 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -35,7 +35,7 @@ void irq_gc_mask_disable_reg(struct irq_data *d)
35{ 35{
36 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 36 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
37 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 40 irq_gc_lock(gc);
41 irq_reg_writel(mask, gc->reg_base + ct->regs.disable); 41 irq_reg_writel(mask, gc->reg_base + ct->regs.disable);
@@ -54,7 +54,7 @@ void irq_gc_mask_set_bit(struct irq_data *d)
54{ 54{
55 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 55 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
56 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 59 irq_gc_lock(gc);
60 *ct->mask_cache |= mask; 60 *ct->mask_cache |= mask;
@@ -73,7 +73,7 @@ void irq_gc_mask_clr_bit(struct irq_data *d)
73{ 73{
74 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 74 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
75 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 78 irq_gc_lock(gc);
79 *ct->mask_cache &= ~mask; 79 *ct->mask_cache &= ~mask;
@@ -92,7 +92,7 @@ void irq_gc_unmask_enable_reg(struct irq_data *d)
92{ 92{
93 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 93 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
94 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 97 irq_gc_lock(gc);
98 irq_reg_writel(mask, gc->reg_base + ct->regs.enable); 98 irq_reg_writel(mask, gc->reg_base + ct->regs.enable);
@@ -108,7 +108,7 @@ void irq_gc_ack_set_bit(struct irq_data *d)
108{ 108{
109 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 109 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
110 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 113 irq_gc_lock(gc);
114 irq_reg_writel(mask, gc->reg_base + ct->regs.ack); 114 irq_reg_writel(mask, gc->reg_base + ct->regs.ack);
@@ -123,7 +123,7 @@ void irq_gc_ack_clr_bit(struct irq_data *d)
123{ 123{
124 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 124 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
125 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 128 irq_gc_lock(gc);
129 irq_reg_writel(mask, gc->reg_base + ct->regs.ack); 129 irq_reg_writel(mask, gc->reg_base + ct->regs.ack);
@@ -138,7 +138,7 @@ void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
138{ 138{
139 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 139 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
140 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 143 irq_gc_lock(gc);
144 irq_reg_writel(mask, gc->reg_base + ct->regs.mask); 144 irq_reg_writel(mask, gc->reg_base + ct->regs.mask);
@@ -154,7 +154,7 @@ void irq_gc_eoi(struct irq_data *d)
154{ 154{
155 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 155 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
156 struct irq_chip_type *ct = irq_data_get_chip_type(d); 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 irq_gc_lock(gc); 159 irq_gc_lock(gc);
160 irq_reg_writel(mask, gc->reg_base + ct->regs.eoi); 160 irq_reg_writel(mask, gc->reg_base + ct->regs.eoi);
@@ -172,7 +172,7 @@ void irq_gc_eoi(struct irq_data *d)
172int irq_gc_set_wake(struct irq_data *d, unsigned int on) 172int irq_gc_set_wake(struct irq_data *d, unsigned int on)
173{ 173{
174 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 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 if (!(mask & gc->wake_enabled)) 177 if (!(mask & gc->wake_enabled))
178 return -EINVAL; 178 return -EINVAL;
@@ -264,6 +264,11 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
264 if (flags & IRQ_GC_INIT_NESTED_LOCK) 264 if (flags & IRQ_GC_INIT_NESTED_LOCK)
265 irq_set_lockdep_class(i, &irq_nested_lock_class); 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 irq_set_chip_and_handler(i, &ct->chip, ct->handler); 272 irq_set_chip_and_handler(i, &ct->chip, ct->handler);
268 irq_set_chip_data(i, gc); 273 irq_set_chip_data(i, gc);
269 irq_modify_status(i, clr, set); 274 irq_modify_status(i, clr, set);