11
11
* it under the terms of the GNU General Public License version 2 as
12
12
* published by the Free Software Foundation.
13
13
*/
14
+ #include <linux/bitops.h>
14
15
#include <linux/init.h>
15
16
#include <linux/module.h>
16
17
#include <linux/interrupt.h>
40
41
#define ICHP_VAL_IRQ (1 << 31)
41
42
#define ICHP_IRQ (i ) (((i) >> 16) & 0x7fff)
42
43
#define IPR_VALID (1 << 31)
43
- #define IRQ_BIT (n ) (((n) - PXA_IRQ(0)) & 0x1f)
44
44
45
45
#define MAX_INTERNAL_IRQS 128
46
46
51
51
static void __iomem * pxa_irq_base ;
52
52
static int pxa_internal_irq_nr ;
53
53
static bool cpu_has_ipr ;
54
+ static struct irq_domain * pxa_irq_domain ;
54
55
55
56
static inline void __iomem * irq_base (int i )
56
57
{
@@ -66,18 +67,20 @@ static inline void __iomem *irq_base(int i)
66
67
void pxa_mask_irq (struct irq_data * d )
67
68
{
68
69
void __iomem * base = irq_data_get_irq_chip_data (d );
70
+ irq_hw_number_t irq = irqd_to_hwirq (d );
69
71
uint32_t icmr = __raw_readl (base + ICMR );
70
72
71
- icmr &= ~( 1 << IRQ_BIT ( d -> irq ) );
73
+ icmr &= ~BIT ( irq & 0x1f );
72
74
__raw_writel (icmr , base + ICMR );
73
75
}
74
76
75
77
void pxa_unmask_irq (struct irq_data * d )
76
78
{
77
79
void __iomem * base = irq_data_get_irq_chip_data (d );
80
+ irq_hw_number_t irq = irqd_to_hwirq (d );
78
81
uint32_t icmr = __raw_readl (base + ICMR );
79
82
80
- icmr |= 1 << IRQ_BIT ( d -> irq );
83
+ icmr |= BIT ( irq & 0x1f );
81
84
__raw_writel (icmr , base + ICMR );
82
85
}
83
86
@@ -118,40 +121,63 @@ asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs)
118
121
} while (1 );
119
122
}
120
123
121
- void __init pxa_init_irq (int irq_nr , int (* fn )(struct irq_data * , unsigned int ))
124
+ static int pxa_irq_map (struct irq_domain * h , unsigned int virq ,
125
+ irq_hw_number_t hw )
122
126
{
123
- int irq , i , n ;
127
+ void __iomem * base = irq_base ( hw / 32 ) ;
124
128
125
- BUG_ON (irq_nr > MAX_INTERNAL_IRQS );
129
+ /* initialize interrupt priority */
130
+ if (cpu_has_ipr )
131
+ __raw_writel (hw | IPR_VALID , pxa_irq_base + IPR (hw ));
132
+
133
+ irq_set_chip_and_handler (virq , & pxa_internal_irq_chip ,
134
+ handle_level_irq );
135
+ irq_set_chip_data (virq , base );
136
+ set_irq_flags (virq , IRQF_VALID );
137
+
138
+ return 0 ;
139
+ }
140
+
141
+ static struct irq_domain_ops pxa_irq_ops = {
142
+ .map = pxa_irq_map ,
143
+ .xlate = irq_domain_xlate_onecell ,
144
+ };
145
+
146
+ static __init void
147
+ pxa_init_irq_common (struct device_node * node , int irq_nr ,
148
+ int (* fn )(struct irq_data * , unsigned int ))
149
+ {
150
+ int n ;
126
151
127
152
pxa_internal_irq_nr = irq_nr ;
128
- cpu_has_ipr = !cpu_is_pxa25x ();
129
- pxa_irq_base = io_p2v (0x40d00000 );
153
+ pxa_irq_domain = irq_domain_add_legacy (node , irq_nr ,
154
+ PXA_IRQ (0 ), 0 ,
155
+ & pxa_irq_ops , NULL );
156
+ if (!pxa_irq_domain )
157
+ panic ("Unable to add PXA IRQ domain\n" );
158
+ irq_set_default_host (pxa_irq_domain );
130
159
131
160
for (n = 0 ; n < irq_nr ; n += 32 ) {
132
161
void __iomem * base = irq_base (n >> 5 );
133
162
134
163
__raw_writel (0 , base + ICMR ); /* disable all IRQs */
135
164
__raw_writel (0 , base + ICLR ); /* all IRQs are IRQ, not FIQ */
136
- for (i = n ; (i < (n + 32 )) && (i < irq_nr ); i ++ ) {
137
- /* initialize interrupt priority */
138
- if (cpu_has_ipr )
139
- __raw_writel (i | IPR_VALID , pxa_irq_base + IPR (i ));
140
-
141
- irq = PXA_IRQ (i );
142
- irq_set_chip_and_handler (irq , & pxa_internal_irq_chip ,
143
- handle_level_irq );
144
- irq_set_chip_data (irq , base );
145
- set_irq_flags (irq , IRQF_VALID );
146
- }
147
165
}
148
-
149
166
/* only unmasked interrupts kick us out of idle */
150
167
__raw_writel (1 , irq_base (0 ) + ICCR );
151
168
152
169
pxa_internal_irq_chip .irq_set_wake = fn ;
153
170
}
154
171
172
+ void __init pxa_init_irq (int irq_nr , int (* fn )(struct irq_data * , unsigned int ))
173
+ {
174
+ BUG_ON (irq_nr > MAX_INTERNAL_IRQS );
175
+
176
+ pxa_irq_base = io_p2v (0x40d00000 );
177
+ cpu_has_ipr = !cpu_is_pxa25x ();
178
+ pxa_init_irq_common (NULL , irq_nr , fn );
179
+ }
180
+
155
181
#ifdef CONFIG_PM
156
182
static unsigned long saved_icmr [MAX_INTERNAL_IRQS /32 ];
157
183
static unsigned long saved_ipr [MAX_INTERNAL_IRQS ];
@@ -203,30 +229,6 @@ struct syscore_ops pxa_irq_syscore_ops = {
203
229
};
204
230
205
231
#ifdef CONFIG_OF
206
- static struct irq_domain * pxa_irq_domain ;
207
-
208
- static int pxa_irq_map (struct irq_domain * h , unsigned int virq ,
209
- irq_hw_number_t hw )
210
- {
211
- void __iomem * base = irq_base (hw / 32 );
212
-
213
- /* initialize interrupt priority */
214
- if (cpu_has_ipr )
215
- __raw_writel (hw | IPR_VALID , pxa_irq_base + IPR (hw ));
216
-
217
- irq_set_chip_and_handler (hw , & pxa_internal_irq_chip ,
218
- handle_level_irq );
219
- irq_set_chip_data (hw , base );
220
- set_irq_flags (hw , IRQF_VALID );
221
-
222
- return 0 ;
223
- }
224
-
225
- static struct irq_domain_ops pxa_irq_ops = {
226
- .map = pxa_irq_map ,
227
- .xlate = irq_domain_xlate_onecell ,
228
- };
229
-
230
232
static const struct of_device_id intc_ids [] __initconst = {
231
233
{ .compatible = "marvell,pxa-intc" , },
232
234
{}
@@ -236,7 +238,7 @@ void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int))
236
238
{
237
239
struct device_node * node ;
238
240
struct resource res ;
239
- int n , ret ;
241
+ int ret ;
240
242
241
243
node = of_find_matching_node (NULL , intc_ids );
242
244
if (!node ) {
@@ -267,23 +269,6 @@ void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int))
267
269
return ;
268
270
}
269
271
270
- pxa_irq_domain = irq_domain_add_legacy (node , pxa_internal_irq_nr , 0 , 0 ,
271
- & pxa_irq_ops , NULL );
272
- if (!pxa_irq_domain )
273
- panic ("Unable to add PXA IRQ domain\n" );
274
-
275
- irq_set_default_host (pxa_irq_domain );
276
-
277
- for (n = 0 ; n < pxa_internal_irq_nr ; n += 32 ) {
278
- void __iomem * base = irq_base (n >> 5 );
279
-
280
- __raw_writel (0 , base + ICMR ); /* disable all IRQs */
281
- __raw_writel (0 , base + ICLR ); /* all IRQs are IRQ, not FIQ */
282
- }
283
-
284
- /* only unmasked interrupts kick us out of idle */
285
- __raw_writel (1 , irq_base (0 ) + ICCR );
286
-
287
- pxa_internal_irq_chip .irq_set_wake = fn ;
272
+ pxa_init_irq_common (node , pxa_internal_irq_nr , fn );
288
273
}
289
274
#endif /* CONFIG_OF */
0 commit comments