13
13
#include <linux/init.h>
14
14
#include <linux/irq.h>
15
15
#include <linux/irqchip.h>
16
+ #include <linux/irqchip/irq-davinci-cp-intc.h>
16
17
#include <linux/irqdomain.h>
17
18
#include <linux/io.h>
18
19
#include <linux/of.h>
19
20
#include <linux/of_address.h>
20
21
#include <linux/of_irq.h>
21
22
22
23
#include <asm/exception.h>
23
- #include <mach/common.h>
24
24
25
25
#define DAVINCI_CP_INTC_CTRL 0x04
26
26
#define DAVINCI_CP_INTC_HOST_CTRL 0x0c
@@ -158,22 +158,15 @@ static const struct irq_domain_ops davinci_cp_intc_irq_domain_ops = {
158
158
.xlate = irq_domain_xlate_onetwocell ,
159
159
};
160
160
161
- static int __init davinci_cp_intc_of_init (struct device_node * node ,
162
- struct device_node * parent )
161
+ static int __init
162
+ davinci_cp_intc_do_init (const struct davinci_cp_intc_config * config ,
163
+ struct device_node * node )
163
164
{
164
- u32 num_irq = davinci_soc_info .intc_irq_num ;
165
- u8 * irq_prio = davinci_soc_info .intc_irq_prios ;
166
- unsigned num_reg = BITS_TO_LONGS (num_irq );
167
- int i , irq_base ;
168
-
169
- if (node ) {
170
- davinci_cp_intc_base = of_iomap (node , 0 );
171
- if (of_property_read_u32 (node , "ti,intc-size" , & num_irq ))
172
- pr_warn ("unable to get intc-size, default to %d\n" ,
173
- num_irq );
174
- } else {
175
- davinci_cp_intc_base = ioremap (davinci_soc_info .intc_base , SZ_8K );
176
- }
165
+ unsigned int num_regs = BITS_TO_LONGS (config -> num_irqs );
166
+ int offset , irq_base ;
167
+
168
+ davinci_cp_intc_base = ioremap (config -> reg .start ,
169
+ resource_size (& config -> reg ));
177
170
if (WARN_ON (!davinci_cp_intc_base ))
178
171
return - EINVAL ;
179
172
@@ -183,59 +176,37 @@ static int __init davinci_cp_intc_of_init(struct device_node *node,
183
176
davinci_cp_intc_write (0 , DAVINCI_CP_INTC_HOST_ENABLE (0 ));
184
177
185
178
/* Disable system interrupts */
186
- for (i = 0 ; i < num_reg ; i ++ )
187
- davinci_cp_intc_write (~0 , DAVINCI_CP_INTC_SYS_ENABLE_CLR (i ));
179
+ for (offset = 0 ; offset < num_regs ; offset ++ )
180
+ davinci_cp_intc_write (~0 ,
181
+ DAVINCI_CP_INTC_SYS_ENABLE_CLR (offset ));
188
182
189
183
/* Set to normal mode, no nesting, no priority hold */
190
184
davinci_cp_intc_write (0 , DAVINCI_CP_INTC_CTRL );
191
185
davinci_cp_intc_write (0 , DAVINCI_CP_INTC_HOST_CTRL );
192
186
193
187
/* Clear system interrupt status */
194
- for (i = 0 ; i < num_reg ; i ++ )
195
- davinci_cp_intc_write (~0 , DAVINCI_CP_INTC_SYS_STAT_CLR (i ));
188
+ for (offset = 0 ; offset < num_regs ; offset ++ )
189
+ davinci_cp_intc_write (~0 ,
190
+ DAVINCI_CP_INTC_SYS_STAT_CLR (offset ));
196
191
197
192
/* Enable nIRQ (what about nFIQ?) */
198
193
davinci_cp_intc_write (1 , DAVINCI_CP_INTC_HOST_ENABLE_IDX_SET );
199
194
200
- /*
201
- * Priority is determined by host channel: lower channel number has
202
- * higher priority i.e. channel 0 has highest priority and channel 31
203
- * had the lowest priority.
204
- */
205
- num_reg = (num_irq + 3 ) >> 2 ; /* 4 channels per register */
206
- if (irq_prio ) {
207
- unsigned j , k ;
208
- u32 val ;
209
-
210
- for (k = i = 0 ; i < num_reg ; i ++ ) {
211
- for (val = j = 0 ; j < 4 ; j ++ , k ++ ) {
212
- val >>= 8 ;
213
- if (k < num_irq )
214
- val |= irq_prio [k ] << 24 ;
215
- }
216
-
217
- davinci_cp_intc_write (val , DAVINCI_CP_INTC_CHAN_MAP (i ));
218
- }
219
- } else {
220
- /*
221
- * Default everything to channel 15 if priority not specified.
222
- * Note that channel 0-1 are mapped to nFIQ and channels 2-31
223
- * are mapped to nIRQ.
224
- */
225
- for (i = 0 ; i < num_reg ; i ++ )
226
- davinci_cp_intc_write (0x0f0f0f0f ,
227
- DAVINCI_CP_INTC_CHAN_MAP (i ));
228
- }
195
+ /* Default all priorities to channel 7. */
196
+ num_regs = (config -> num_irqs + 3 ) >> 2 ; /* 4 channels per register */
197
+ for (offset = 0 ; offset < num_regs ; offset ++ )
198
+ davinci_cp_intc_write (0x07070707 ,
199
+ DAVINCI_CP_INTC_CHAN_MAP (offset ));
229
200
230
- irq_base = irq_alloc_descs (-1 , 0 , num_irq , 0 );
201
+ irq_base = irq_alloc_descs (-1 , 0 , config -> num_irqs , 0 );
231
202
if (irq_base < 0 ) {
232
203
pr_warn ("Couldn't allocate IRQ numbers\n" );
233
204
irq_base = 0 ;
234
205
}
235
206
236
207
/* create a legacy host */
237
208
davinci_cp_intc_irq_domain = irq_domain_add_legacy (
238
- node , num_irq , irq_base , 0 ,
209
+ node , config -> num_irqs , irq_base , 0 ,
239
210
& davinci_cp_intc_irq_domain_ops , NULL );
240
211
241
212
if (!davinci_cp_intc_irq_domain ) {
@@ -251,9 +222,31 @@ static int __init davinci_cp_intc_of_init(struct device_node *node,
251
222
return 0 ;
252
223
}
253
224
254
- void __init davinci_cp_intc_init (void )
225
+ int __init davinci_cp_intc_init (const struct davinci_cp_intc_config * config )
255
226
{
256
- davinci_cp_intc_of_init ( NULL , NULL );
227
+ return davinci_cp_intc_do_init ( config , NULL );
257
228
}
258
229
230
+ static int __init davinci_cp_intc_of_init (struct device_node * node ,
231
+ struct device_node * parent )
232
+ {
233
+ struct davinci_cp_intc_config config = { };
234
+ int ret ;
235
+
236
+ ret = of_address_to_resource (node , 0 , & config .reg );
237
+ if (ret ) {
238
+ pr_err ("%s: unable to get the register range from device-tree\n" ,
239
+ __func__ );
240
+ return ret ;
241
+ }
242
+
243
+ ret = of_property_read_u32 (node , "ti,intc-size" , & config .num_irqs );
244
+ if (ret ) {
245
+ pr_err ("%s: unable to read the 'ti,intc-size' property\n" ,
246
+ __func__ );
247
+ return ret ;
248
+ }
249
+
250
+ return davinci_cp_intc_do_init (& config , node );
251
+ }
259
252
IRQCHIP_DECLARE (cp_intc , "ti,cp-intc" , davinci_cp_intc_of_init );
0 commit comments