aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2013-06-10 06:52:03 -0400
committerGrant Likely <grant.likely@linaro.org>2013-06-10 06:52:03 -0400
commit5e8bd41abb24a3189119233e33c5dfecfad46cb3 (patch)
treef08db705473a32525291fb4df6494d700c359513
parent317ddd256b9c24b0d78fa8018f80f1e495481a10 (diff)
parente8bd834f73714378ef110a64287db1b77033c8da (diff)
Merge remote-tracking branch 'tip/irq/for-arm' into irqdomain/next
-rw-r--r--include/linux/irq.h47
-rw-r--r--include/linux/irqdomain.h12
-rw-r--r--kernel/irq/generic-chip.c301
-rw-r--r--kernel/irq/irqdomain.c6
4 files changed, 316 insertions, 50 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index bc4e06611958..298a9b9ce675 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;
@@ -294,6 +296,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
294 * @irq_suspend: function called from core code on suspend once per chip 296 * @irq_suspend: function called from core code on suspend once per chip
295 * @irq_resume: function called from core code on resume once per chip 297 * @irq_resume: function called from core code on resume once per chip
296 * @irq_pm_shutdown: function called from core code on shutdown once per chip 298 * @irq_pm_shutdown: function called from core code on shutdown once per chip
299 * @irq_calc_mask: Optional function to set irq_data.mask for special cases
297 * @irq_print_chip: optional to print special chip info in show_interrupts 300 * @irq_print_chip: optional to print special chip info in show_interrupts
298 * @flags: chip specific flags 301 * @flags: chip specific flags
299 */ 302 */
@@ -325,6 +328,8 @@ struct irq_chip {
325 void (*irq_resume)(struct irq_data *data); 328 void (*irq_resume)(struct irq_data *data);
326 void (*irq_pm_shutdown)(struct irq_data *data); 329 void (*irq_pm_shutdown)(struct irq_data *data);
327 330
331 void (*irq_calc_mask)(struct irq_data *data);
332
328 void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); 333 void (*irq_print_chip)(struct irq_data *data, struct seq_file *p);
329 334
330 unsigned long flags; 335 unsigned long flags;
@@ -644,6 +649,8 @@ struct irq_chip_regs {
644 * @regs: Register offsets for this chip 649 * @regs: Register offsets for this chip
645 * @handler: Flow handler associated with this chip 650 * @handler: Flow handler associated with this chip
646 * @type: Chip can handle these flow types 651 * @type: Chip can handle these flow types
652 * @mask_cache_priv: Cached mask register private to the chip type
653 * @mask_cache: Pointer to cached mask register
647 * 654 *
648 * A irq_generic_chip can have several instances of irq_chip_type when 655 * A irq_generic_chip can have several instances of irq_chip_type when
649 * it requires different functions and register offsets for different 656 * it requires different functions and register offsets for different
@@ -654,6 +661,8 @@ struct irq_chip_type {
654 struct irq_chip_regs regs; 661 struct irq_chip_regs regs;
655 irq_flow_handler_t handler; 662 irq_flow_handler_t handler;
656 u32 type; 663 u32 type;
664 u32 mask_cache_priv;
665 u32 *mask_cache;
657}; 666};
658 667
659/** 668/**
@@ -662,13 +671,16 @@ struct irq_chip_type {
662 * @reg_base: Register base address (virtual) 671 * @reg_base: Register base address (virtual)
663 * @irq_base: Interrupt base nr for this chip 672 * @irq_base: Interrupt base nr for this chip
664 * @irq_cnt: Number of interrupts handled by this chip 673 * @irq_cnt: Number of interrupts handled by this chip
665 * @mask_cache: Cached mask register 674 * @mask_cache: Cached mask register shared between all chip types
666 * @type_cache: Cached type register 675 * @type_cache: Cached type register
667 * @polarity_cache: Cached polarity register 676 * @polarity_cache: Cached polarity register
668 * @wake_enabled: Interrupt can wakeup from suspend 677 * @wake_enabled: Interrupt can wakeup from suspend
669 * @wake_active: Interrupt is marked as an wakeup from suspend source 678 * @wake_active: Interrupt is marked as an wakeup from suspend source
670 * @num_ct: Number of available irq_chip_type instances (usually 1) 679 * @num_ct: Number of available irq_chip_type instances (usually 1)
671 * @private: Private data for non generic chip callbacks 680 * @private: Private data for non generic chip callbacks
681 * @installed: bitfield to denote installed interrupts
682 * @unused: bitfield to denote unused interrupts
683 * @domain: irq domain pointer
672 * @list: List head for keeping track of instances 684 * @list: List head for keeping track of instances
673 * @chip_types: Array of interrupt irq_chip_types 685 * @chip_types: Array of interrupt irq_chip_types
674 * 686 *
@@ -690,6 +702,9 @@ struct irq_chip_generic {
690 u32 wake_active; 702 u32 wake_active;
691 unsigned int num_ct; 703 unsigned int num_ct;
692 void *private; 704 void *private;
705 unsigned long installed;
706 unsigned long unused;
707 struct irq_domain *domain;
693 struct list_head list; 708 struct list_head list;
694 struct irq_chip_type chip_types[0]; 709 struct irq_chip_type chip_types[0];
695}; 710};
@@ -700,10 +715,32 @@ struct irq_chip_generic {
700 * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for 715 * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for
701 * irq chips which need to call irq_set_wake() on 716 * irq chips which need to call irq_set_wake() on
702 * the parent irq. Usually GPIO implementations 717 * the parent irq. Usually GPIO implementations
718 * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private
719 * @IRQ_GC_NO_MASK: Do not calculate irq_data->mask
703 */ 720 */
704enum irq_gc_flags { 721enum irq_gc_flags {
705 IRQ_GC_INIT_MASK_CACHE = 1 << 0, 722 IRQ_GC_INIT_MASK_CACHE = 1 << 0,
706 IRQ_GC_INIT_NESTED_LOCK = 1 << 1, 723 IRQ_GC_INIT_NESTED_LOCK = 1 << 1,
724 IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2,
725 IRQ_GC_NO_MASK = 1 << 3,
726};
727
728/*
729 * struct irq_domain_chip_generic - Generic irq chip data structure for irq domains
730 * @irqs_per_chip: Number of interrupts per chip
731 * @num_chips: Number of chips
732 * @irq_flags_to_set: IRQ* flags to set on irq setup
733 * @irq_flags_to_clear: IRQ* flags to clear on irq setup
734 * @gc_flags: Generic chip specific setup flags
735 * @gc: Array of pointers to generic interrupt chips
736 */
737struct irq_domain_chip_generic {
738 unsigned int irqs_per_chip;
739 unsigned int num_chips;
740 unsigned int irq_flags_to_clear;
741 unsigned int irq_flags_to_set;
742 enum irq_gc_flags gc_flags;
743 struct irq_chip_generic *gc[0];
707}; 744};
708 745
709/* Generic chip callback functions */ 746/* Generic chip callback functions */
@@ -729,6 +766,14 @@ int irq_setup_alt_chip(struct irq_data *d, unsigned int type);
729void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, 766void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
730 unsigned int clr, unsigned int set); 767 unsigned int clr, unsigned int set);
731 768
769struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
770int irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
771 int num_ct, const char *name,
772 irq_flow_handler_t handler,
773 unsigned int clr, unsigned int set,
774 enum irq_gc_flags flags);
775
776
732static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d) 777static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d)
733{ 778{
734 return container_of(d->chip, struct irq_chip_type, chip); 779 return container_of(d->chip, struct irq_chip_type, chip);
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 0d5b17bf5e51..ba2c708adcff 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -66,6 +66,10 @@ struct irq_domain_ops {
66 unsigned long *out_hwirq, unsigned int *out_type); 66 unsigned long *out_hwirq, unsigned int *out_type);
67}; 67};
68 68
69extern struct irq_domain_ops irq_generic_chip_ops;
70
71struct irq_domain_chip_generic;
72
69/** 73/**
70 * struct irq_domain - Hardware interrupt number translation object 74 * struct irq_domain - Hardware interrupt number translation object
71 * @link: Element in global irq_domain list. 75 * @link: Element in global irq_domain list.
@@ -109,8 +113,16 @@ struct irq_domain {
109 113
110 /* Optional device node pointer */ 114 /* Optional device node pointer */
111 struct device_node *of_node; 115 struct device_node *of_node;
116 /* Optional pointer to generic interrupt chips */
117 struct irq_domain_chip_generic *gc;
112}; 118};
113 119
120#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
121 * ie. legacy 8259, gets irqs 1..15 */
122#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
123#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
124#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
125
114#ifdef CONFIG_IRQ_DOMAIN 126#ifdef CONFIG_IRQ_DOMAIN
115struct irq_domain *irq_domain_add_simple(struct device_node *of_node, 127struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
116 unsigned int size, 128 unsigned int size,
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index c89295a8f668..95575d8d5392 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -7,6 +7,7 @@
7#include <linux/irq.h> 7#include <linux/irq.h>
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <linux/export.h> 9#include <linux/export.h>
10#include <linux/irqdomain.h>
10#include <linux/interrupt.h> 11#include <linux/interrupt.h>
11#include <linux/kernel_stat.h> 12#include <linux/kernel_stat.h>
12#include <linux/syscore_ops.h> 13#include <linux/syscore_ops.h>
@@ -16,11 +17,6 @@
16static LIST_HEAD(gc_list); 17static LIST_HEAD(gc_list);
17static DEFINE_RAW_SPINLOCK(gc_lock); 18static DEFINE_RAW_SPINLOCK(gc_lock);
18 19
19static inline struct irq_chip_regs *cur_regs(struct irq_data *d)
20{
21 return &container_of(d->chip, struct irq_chip_type, chip)->regs;
22}
23
24/** 20/**
25 * irq_gc_noop - NOOP function 21 * irq_gc_noop - NOOP function
26 * @d: irq_data 22 * @d: irq_data
@@ -39,11 +35,12 @@ void irq_gc_noop(struct irq_data *d)
39void irq_gc_mask_disable_reg(struct irq_data *d) 35void irq_gc_mask_disable_reg(struct irq_data *d)
40{ 36{
41 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 37 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
42 u32 mask = 1 << (d->irq - gc->irq_base); 38 struct irq_chip_type *ct = irq_data_get_chip_type(d);
39 u32 mask = d->mask;
43 40
44 irq_gc_lock(gc); 41 irq_gc_lock(gc);
45 irq_reg_writel(mask, gc->reg_base + cur_regs(d)->disable); 42 irq_reg_writel(mask, gc->reg_base + ct->regs.disable);
46 gc->mask_cache &= ~mask; 43 *ct->mask_cache &= ~mask;
47 irq_gc_unlock(gc); 44 irq_gc_unlock(gc);
48} 45}
49 46
@@ -57,11 +54,12 @@ void irq_gc_mask_disable_reg(struct irq_data *d)
57void irq_gc_mask_set_bit(struct irq_data *d) 54void irq_gc_mask_set_bit(struct irq_data *d)
58{ 55{
59 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 56 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
60 u32 mask = 1 << (d->irq - gc->irq_base); 57 struct irq_chip_type *ct = irq_data_get_chip_type(d);
58 u32 mask = d->mask;
61 59
62 irq_gc_lock(gc); 60 irq_gc_lock(gc);
63 gc->mask_cache |= mask; 61 *ct->mask_cache |= mask;
64 irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask); 62 irq_reg_writel(*ct->mask_cache, gc->reg_base + ct->regs.mask);
65 irq_gc_unlock(gc); 63 irq_gc_unlock(gc);
66} 64}
67 65
@@ -75,11 +73,12 @@ void irq_gc_mask_set_bit(struct irq_data *d)
75void irq_gc_mask_clr_bit(struct irq_data *d) 73void irq_gc_mask_clr_bit(struct irq_data *d)
76{ 74{
77 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 75 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
78 u32 mask = 1 << (d->irq - gc->irq_base); 76 struct irq_chip_type *ct = irq_data_get_chip_type(d);
77 u32 mask = d->mask;
79 78
80 irq_gc_lock(gc); 79 irq_gc_lock(gc);
81 gc->mask_cache &= ~mask; 80 *ct->mask_cache &= ~mask;
82 irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask); 81 irq_reg_writel(*ct->mask_cache, gc->reg_base + ct->regs.mask);
83 irq_gc_unlock(gc); 82 irq_gc_unlock(gc);
84} 83}
85 84
@@ -93,11 +92,12 @@ void irq_gc_mask_clr_bit(struct irq_data *d)
93void irq_gc_unmask_enable_reg(struct irq_data *d) 92void irq_gc_unmask_enable_reg(struct irq_data *d)
94{ 93{
95 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 94 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
96 u32 mask = 1 << (d->irq - gc->irq_base); 95 struct irq_chip_type *ct = irq_data_get_chip_type(d);
96 u32 mask = d->mask;
97 97
98 irq_gc_lock(gc); 98 irq_gc_lock(gc);
99 irq_reg_writel(mask, gc->reg_base + cur_regs(d)->enable); 99 irq_reg_writel(mask, gc->reg_base + ct->regs.enable);
100 gc->mask_cache |= mask; 100 *ct->mask_cache |= mask;
101 irq_gc_unlock(gc); 101 irq_gc_unlock(gc);
102} 102}
103 103
@@ -108,10 +108,11 @@ void irq_gc_unmask_enable_reg(struct irq_data *d)
108void irq_gc_ack_set_bit(struct irq_data *d) 108void irq_gc_ack_set_bit(struct irq_data *d)
109{ 109{
110 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 110 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
111 u32 mask = 1 << (d->irq - gc->irq_base); 111 struct irq_chip_type *ct = irq_data_get_chip_type(d);
112 u32 mask = d->mask;
112 113
113 irq_gc_lock(gc); 114 irq_gc_lock(gc);
114 irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); 115 irq_reg_writel(mask, gc->reg_base + ct->regs.ack);
115 irq_gc_unlock(gc); 116 irq_gc_unlock(gc);
116} 117}
117 118
@@ -122,10 +123,11 @@ void irq_gc_ack_set_bit(struct irq_data *d)
122void irq_gc_ack_clr_bit(struct irq_data *d) 123void irq_gc_ack_clr_bit(struct irq_data *d)
123{ 124{
124 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 125 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
125 u32 mask = ~(1 << (d->irq - gc->irq_base)); 126 struct irq_chip_type *ct = irq_data_get_chip_type(d);
127 u32 mask = ~d->mask;
126 128
127 irq_gc_lock(gc); 129 irq_gc_lock(gc);
128 irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); 130 irq_reg_writel(mask, gc->reg_base + ct->regs.ack);
129 irq_gc_unlock(gc); 131 irq_gc_unlock(gc);
130} 132}
131 133
@@ -136,11 +138,12 @@ void irq_gc_ack_clr_bit(struct irq_data *d)
136void irq_gc_mask_disable_reg_and_ack(struct irq_data *d) 138void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
137{ 139{
138 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 140 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
139 u32 mask = 1 << (d->irq - gc->irq_base); 141 struct irq_chip_type *ct = irq_data_get_chip_type(d);
142 u32 mask = d->mask;
140 143
141 irq_gc_lock(gc); 144 irq_gc_lock(gc);
142 irq_reg_writel(mask, gc->reg_base + cur_regs(d)->mask); 145 irq_reg_writel(mask, gc->reg_base + ct->regs.mask);
143 irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); 146 irq_reg_writel(mask, gc->reg_base + ct->regs.ack);
144 irq_gc_unlock(gc); 147 irq_gc_unlock(gc);
145} 148}
146 149
@@ -151,10 +154,11 @@ void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
151void irq_gc_eoi(struct irq_data *d) 154void irq_gc_eoi(struct irq_data *d)
152{ 155{
153 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 156 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
154 u32 mask = 1 << (d->irq - gc->irq_base); 157 struct irq_chip_type *ct = irq_data_get_chip_type(d);
158 u32 mask = d->mask;
155 159
156 irq_gc_lock(gc); 160 irq_gc_lock(gc);
157 irq_reg_writel(mask, gc->reg_base + cur_regs(d)->eoi); 161 irq_reg_writel(mask, gc->reg_base + ct->regs.eoi);
158 irq_gc_unlock(gc); 162 irq_gc_unlock(gc);
159} 163}
160 164
@@ -169,7 +173,7 @@ void irq_gc_eoi(struct irq_data *d)
169int irq_gc_set_wake(struct irq_data *d, unsigned int on) 173int irq_gc_set_wake(struct irq_data *d, unsigned int on)
170{ 174{
171 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 175 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
172 u32 mask = 1 << (d->irq - gc->irq_base); 176 u32 mask = d->mask;
173 177
174 if (!(mask & gc->wake_enabled)) 178 if (!(mask & gc->wake_enabled))
175 return -EINVAL; 179 return -EINVAL;
@@ -183,6 +187,19 @@ int irq_gc_set_wake(struct irq_data *d, unsigned int on)
183 return 0; 187 return 0;
184} 188}
185 189
190static void
191irq_init_generic_chip(struct irq_chip_generic *gc, const char *name,
192 int num_ct, unsigned int irq_base,
193 void __iomem *reg_base, irq_flow_handler_t handler)
194{
195 raw_spin_lock_init(&gc->lock);
196 gc->num_ct = num_ct;
197 gc->irq_base = irq_base;
198 gc->reg_base = reg_base;
199 gc->chip_types->chip.name = name;
200 gc->chip_types->handler = handler;
201}
202
186/** 203/**
187 * irq_alloc_generic_chip - Allocate a generic chip and initialize it 204 * irq_alloc_generic_chip - Allocate a generic chip and initialize it
188 * @name: Name of the irq chip 205 * @name: Name of the irq chip
@@ -203,17 +220,115 @@ irq_alloc_generic_chip(const char *name, int num_ct, unsigned int irq_base,
203 220
204 gc = kzalloc(sz, GFP_KERNEL); 221 gc = kzalloc(sz, GFP_KERNEL);
205 if (gc) { 222 if (gc) {
206 raw_spin_lock_init(&gc->lock); 223 irq_init_generic_chip(gc, name, num_ct, irq_base, reg_base,
207 gc->num_ct = num_ct; 224 handler);
208 gc->irq_base = irq_base;
209 gc->reg_base = reg_base;
210 gc->chip_types->chip.name = name;
211 gc->chip_types->handler = handler;
212 } 225 }
213 return gc; 226 return gc;
214} 227}
215EXPORT_SYMBOL_GPL(irq_alloc_generic_chip); 228EXPORT_SYMBOL_GPL(irq_alloc_generic_chip);
216 229
230static void
231irq_gc_init_mask_cache(struct irq_chip_generic *gc, enum irq_gc_flags flags)
232{
233 struct irq_chip_type *ct = gc->chip_types;
234 u32 *mskptr = &gc->mask_cache, mskreg = ct->regs.mask;
235 int i;
236
237 for (i = 0; i < gc->num_ct; i++) {
238 if (flags & IRQ_GC_MASK_CACHE_PER_TYPE) {
239 mskptr = &ct[i].mask_cache_priv;
240 mskreg = ct[i].regs.mask;
241 }
242 ct[i].mask_cache = mskptr;
243 if (flags & IRQ_GC_INIT_MASK_CACHE)
244 *mskptr = irq_reg_readl(gc->reg_base + mskreg);
245 }
246}
247
248/**
249 * irq_alloc_domain_generic_chip - Allocate generic chips for an irq domain
250 * @d: irq domain for which to allocate chips
251 * @irqs_per_chip: Number of interrupts each chip handles
252 * @num_ct: Number of irq_chip_type instances associated with this
253 * @name: Name of the irq chip
254 * @handler: Default flow handler associated with these chips
255 * @clr: IRQ_* bits to clear in the mapping function
256 * @set: IRQ_* bits to set in the mapping function
257 */
258int irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
259 int num_ct, const char *name,
260 irq_flow_handler_t handler,
261 unsigned int clr, unsigned int set,
262 enum irq_gc_flags gcflags)
263{
264 struct irq_domain_chip_generic *dgc;
265 struct irq_chip_generic *gc;
266 int numchips, sz, i;
267 unsigned long flags;
268 void *tmp;
269
270 if (d->gc)
271 return -EBUSY;
272
273 if (d->revmap_type != IRQ_DOMAIN_MAP_LINEAR)
274 return -EINVAL;
275
276 numchips = d->revmap_data.linear.size / irqs_per_chip;
277 if (!numchips)
278 return -EINVAL;
279
280 /* Allocate a pointer, generic chip and chiptypes for each chip */
281 sz = sizeof(*dgc) + numchips * sizeof(gc);
282 sz += numchips * (sizeof(*gc) + num_ct * sizeof(struct irq_chip_type));
283
284 tmp = dgc = kzalloc(sz, GFP_KERNEL);
285 if (!dgc)
286 return -ENOMEM;
287 dgc->irqs_per_chip = irqs_per_chip;
288 dgc->num_chips = numchips;
289 dgc->irq_flags_to_set = set;
290 dgc->irq_flags_to_clear = clr;
291 dgc->gc_flags = gcflags;
292 d->gc = dgc;
293
294 /* Calc pointer to the first generic chip */
295 tmp += sizeof(*dgc) + numchips * sizeof(gc);
296 for (i = 0; i < numchips; i++) {
297 /* Store the pointer to the generic chip */
298 dgc->gc[i] = gc = tmp;
299 irq_init_generic_chip(gc, name, num_ct, i * irqs_per_chip,
300 NULL, handler);
301 gc->domain = d;
302 raw_spin_lock_irqsave(&gc_lock, flags);
303 list_add_tail(&gc->list, &gc_list);
304 raw_spin_unlock_irqrestore(&gc_lock, flags);
305 /* Calc pointer to the next generic chip */
306 tmp += sizeof(*gc) + num_ct * sizeof(struct irq_chip_type);
307 }
308 return 0;
309}
310EXPORT_SYMBOL_GPL(irq_alloc_domain_generic_chips);
311
312/**
313 * irq_get_domain_generic_chip - Get a pointer to the generic chip of a hw_irq
314 * @d: irq domain pointer
315 * @hw_irq: Hardware interrupt number
316 */
317struct irq_chip_generic *
318irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq)
319{
320 struct irq_domain_chip_generic *dgc = d->gc;
321 int idx;
322
323 if (!dgc)
324 return NULL;
325 idx = hw_irq / dgc->irqs_per_chip;
326 if (idx >= dgc->num_chips)
327 return NULL;
328 return dgc->gc[idx];
329}
330EXPORT_SYMBOL_GPL(irq_get_domain_generic_chip);
331
217/* 332/*
218 * Separate lockdep class for interrupt chip which can nest irq_desc 333 * Separate lockdep class for interrupt chip which can nest irq_desc
219 * lock. 334 * lock.
@@ -221,6 +336,69 @@ EXPORT_SYMBOL_GPL(irq_alloc_generic_chip);
221static struct lock_class_key irq_nested_lock_class; 336static struct lock_class_key irq_nested_lock_class;
222 337
223/** 338/**
339 * irq_map_generic_chip - Map a generic chip for an irq domain
340 */
341static int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
342 irq_hw_number_t hw_irq)
343{
344 struct irq_data *data = irq_get_irq_data(virq);
345 struct irq_domain_chip_generic *dgc = d->gc;
346 struct irq_chip_generic *gc;
347 struct irq_chip_type *ct;
348 struct irq_chip *chip;
349 unsigned long flags;
350 int idx;
351
352 if (!d->gc)
353 return -ENODEV;
354
355 idx = hw_irq / dgc->irqs_per_chip;
356 if (idx >= dgc->num_chips)
357 return -EINVAL;
358 gc = dgc->gc[idx];
359
360 idx = hw_irq % dgc->irqs_per_chip;
361
362 if (test_bit(idx, &gc->unused))
363 return -ENOTSUPP;
364
365 if (test_bit(idx, &gc->installed))
366 return -EBUSY;
367
368 ct = gc->chip_types;
369 chip = &ct->chip;
370
371 /* We only init the cache for the first mapping of a generic chip */
372 if (!gc->installed) {
373 raw_spin_lock_irqsave(&gc->lock, flags);
374 irq_gc_init_mask_cache(gc, dgc->gc_flags);
375 raw_spin_unlock_irqrestore(&gc->lock, flags);
376 }
377
378 /* Mark the interrupt as installed */
379 set_bit(idx, &gc->installed);
380
381 if (dgc->gc_flags & IRQ_GC_INIT_NESTED_LOCK)
382 irq_set_lockdep_class(virq, &irq_nested_lock_class);
383
384 if (chip->irq_calc_mask)
385 chip->irq_calc_mask(data);
386 else
387 data->mask = 1 << idx;
388
389 irq_set_chip_and_handler(virq, chip, ct->handler);
390 irq_set_chip_data(virq, gc);
391 irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set);
392 return 0;
393}
394
395struct irq_domain_ops irq_generic_chip_ops = {
396 .map = irq_map_generic_chip,
397 .xlate = irq_domain_xlate_onetwocell,
398};
399EXPORT_SYMBOL_GPL(irq_generic_chip_ops);
400
401/**
224 * irq_setup_generic_chip - Setup a range of interrupts with a generic chip 402 * irq_setup_generic_chip - Setup a range of interrupts with a generic chip
225 * @gc: Generic irq chip holding all data 403 * @gc: Generic irq chip holding all data
226 * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base 404 * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base
@@ -237,15 +415,14 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
237 unsigned int set) 415 unsigned int set)
238{ 416{
239 struct irq_chip_type *ct = gc->chip_types; 417 struct irq_chip_type *ct = gc->chip_types;
418 struct irq_chip *chip = &ct->chip;
240 unsigned int i; 419 unsigned int i;
241 420
242 raw_spin_lock(&gc_lock); 421 raw_spin_lock(&gc_lock);
243 list_add_tail(&gc->list, &gc_list); 422 list_add_tail(&gc->list, &gc_list);
244 raw_spin_unlock(&gc_lock); 423 raw_spin_unlock(&gc_lock);
245 424
246 /* Init mask cache ? */ 425 irq_gc_init_mask_cache(gc, flags);
247 if (flags & IRQ_GC_INIT_MASK_CACHE)
248 gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask);
249 426
250 for (i = gc->irq_base; msk; msk >>= 1, i++) { 427 for (i = gc->irq_base; msk; msk >>= 1, i++) {
251 if (!(msk & 0x01)) 428 if (!(msk & 0x01))
@@ -254,7 +431,15 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
254 if (flags & IRQ_GC_INIT_NESTED_LOCK) 431 if (flags & IRQ_GC_INIT_NESTED_LOCK)
255 irq_set_lockdep_class(i, &irq_nested_lock_class); 432 irq_set_lockdep_class(i, &irq_nested_lock_class);
256 433
257 irq_set_chip_and_handler(i, &ct->chip, ct->handler); 434 if (!(flags & IRQ_GC_NO_MASK)) {
435 struct irq_data *d = irq_get_irq_data(i);
436
437 if (chip->irq_calc_mask)
438 chip->irq_calc_mask(d);
439 else
440 d->mask = 1 << (i - gc->irq_base);
441 }
442 irq_set_chip_and_handler(i, chip, ct->handler);
258 irq_set_chip_data(i, gc); 443 irq_set_chip_data(i, gc);
259 irq_modify_status(i, clr, set); 444 irq_modify_status(i, clr, set);
260 } 445 }
@@ -317,6 +502,24 @@ void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
317} 502}
318EXPORT_SYMBOL_GPL(irq_remove_generic_chip); 503EXPORT_SYMBOL_GPL(irq_remove_generic_chip);
319 504
505static struct irq_data *irq_gc_get_irq_data(struct irq_chip_generic *gc)
506{
507 unsigned int virq;
508
509 if (!gc->domain)
510 return irq_get_irq_data(gc->irq_base);
511
512 /*
513 * We don't know which of the irqs has been actually
514 * installed. Use the first one.
515 */
516 if (!gc->installed)
517 return NULL;
518
519 virq = irq_find_mapping(gc->domain, gc->irq_base + __ffs(gc->installed));
520 return virq ? irq_get_irq_data(virq) : NULL;
521}
522
320#ifdef CONFIG_PM 523#ifdef CONFIG_PM
321static int irq_gc_suspend(void) 524static int irq_gc_suspend(void)
322{ 525{
@@ -325,8 +528,12 @@ static int irq_gc_suspend(void)
325 list_for_each_entry(gc, &gc_list, list) { 528 list_for_each_entry(gc, &gc_list, list) {
326 struct irq_chip_type *ct = gc->chip_types; 529 struct irq_chip_type *ct = gc->chip_types;
327 530
328 if (ct->chip.irq_suspend) 531 if (ct->chip.irq_suspend) {
329 ct->chip.irq_suspend(irq_get_irq_data(gc->irq_base)); 532 struct irq_data *data = irq_gc_get_irq_data(gc);
533
534 if (data)
535 ct->chip.irq_suspend(data);
536 }
330 } 537 }
331 return 0; 538 return 0;
332} 539}
@@ -338,8 +545,12 @@ static void irq_gc_resume(void)
338 list_for_each_entry(gc, &gc_list, list) { 545 list_for_each_entry(gc, &gc_list, list) {
339 struct irq_chip_type *ct = gc->chip_types; 546 struct irq_chip_type *ct = gc->chip_types;
340 547
341 if (ct->chip.irq_resume) 548 if (ct->chip.irq_resume) {
342 ct->chip.irq_resume(irq_get_irq_data(gc->irq_base)); 549 struct irq_data *data = irq_gc_get_irq_data(gc);
550
551 if (data)
552 ct->chip.irq_resume(data);
553 }
343 } 554 }
344} 555}
345#else 556#else
@@ -354,8 +565,12 @@ static void irq_gc_shutdown(void)
354 list_for_each_entry(gc, &gc_list, list) { 565 list_for_each_entry(gc, &gc_list, list) {
355 struct irq_chip_type *ct = gc->chip_types; 566 struct irq_chip_type *ct = gc->chip_types;
356 567
357 if (ct->chip.irq_pm_shutdown) 568 if (ct->chip.irq_pm_shutdown) {
358 ct->chip.irq_pm_shutdown(irq_get_irq_data(gc->irq_base)); 569 struct irq_data *data = irq_gc_get_irq_data(gc);
570
571 if (data)
572 ct->chip.irq_pm_shutdown(data);
573 }
359 } 574 }
360} 575}
361 576
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 54a4d5223238..20b677dd0b27 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -16,12 +16,6 @@
16#include <linux/smp.h> 16#include <linux/smp.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18 18
19#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
20 * ie. legacy 8259, gets irqs 1..15 */
21#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
22#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
23#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
24
25static LIST_HEAD(irq_domain_list); 19static LIST_HEAD(irq_domain_list);
26static DEFINE_MUTEX(irq_domain_mutex); 20static DEFINE_MUTEX(irq_domain_mutex);
27 21