@@ -38,29 +38,31 @@ struct xintc_irq_chip {
38
38
void __iomem * base ;
39
39
struct irq_domain * root_domain ;
40
40
u32 intr_mask ;
41
+ u32 nr_irq ;
41
42
};
42
43
43
- static struct xintc_irq_chip * xintc_irqc ;
44
+ static struct xintc_irq_chip * primary_intc ;
44
45
45
- static void xintc_write (int reg , u32 data )
46
+ static void xintc_write (struct xintc_irq_chip * irqc , int reg , u32 data )
46
47
{
47
48
if (static_branch_unlikely (& xintc_is_be ))
48
- iowrite32be (data , xintc_irqc -> base + reg );
49
+ iowrite32be (data , irqc -> base + reg );
49
50
else
50
- iowrite32 (data , xintc_irqc -> base + reg );
51
+ iowrite32 (data , irqc -> base + reg );
51
52
}
52
53
53
- static unsigned int xintc_read (int reg )
54
+ static u32 xintc_read (struct xintc_irq_chip * irqc , int reg )
54
55
{
55
56
if (static_branch_unlikely (& xintc_is_be ))
56
- return ioread32be (xintc_irqc -> base + reg );
57
+ return ioread32be (irqc -> base + reg );
57
58
else
58
- return ioread32 (xintc_irqc -> base + reg );
59
+ return ioread32 (irqc -> base + reg );
59
60
}
60
61
61
62
static void intc_enable_or_unmask (struct irq_data * d )
62
63
{
63
- unsigned long mask = 1 << d -> hwirq ;
64
+ struct xintc_irq_chip * irqc = irq_data_get_irq_chip_data (d );
65
+ unsigned long mask = BIT (d -> hwirq );
64
66
65
67
pr_debug ("irq-xilinx: enable_or_unmask: %ld\n" , d -> hwirq );
66
68
@@ -69,30 +71,35 @@ static void intc_enable_or_unmask(struct irq_data *d)
69
71
* acks the irq before calling the interrupt handler
70
72
*/
71
73
if (irqd_is_level_type (d ))
72
- xintc_write (IAR , mask );
74
+ xintc_write (irqc , IAR , mask );
73
75
74
- xintc_write (SIE , mask );
76
+ xintc_write (irqc , SIE , mask );
75
77
}
76
78
77
79
static void intc_disable_or_mask (struct irq_data * d )
78
80
{
81
+ struct xintc_irq_chip * irqc = irq_data_get_irq_chip_data (d );
82
+
79
83
pr_debug ("irq-xilinx: disable: %ld\n" , d -> hwirq );
80
- xintc_write (CIE , 1 << d -> hwirq );
84
+ xintc_write (irqc , CIE , BIT ( d -> hwirq ) );
81
85
}
82
86
83
87
static void intc_ack (struct irq_data * d )
84
88
{
89
+ struct xintc_irq_chip * irqc = irq_data_get_irq_chip_data (d );
90
+
85
91
pr_debug ("irq-xilinx: ack: %ld\n" , d -> hwirq );
86
- xintc_write (IAR , 1 << d -> hwirq );
92
+ xintc_write (irqc , IAR , BIT ( d -> hwirq ) );
87
93
}
88
94
89
95
static void intc_mask_ack (struct irq_data * d )
90
96
{
91
- unsigned long mask = 1 << d -> hwirq ;
97
+ struct xintc_irq_chip * irqc = irq_data_get_irq_chip_data (d );
98
+ unsigned long mask = BIT (d -> hwirq );
92
99
93
100
pr_debug ("irq-xilinx: disable_and_ack: %ld\n" , d -> hwirq );
94
- xintc_write (CIE , mask );
95
- xintc_write (IAR , mask );
101
+ xintc_write (irqc , CIE , mask );
102
+ xintc_write (irqc , IAR , mask );
96
103
}
97
104
98
105
static struct irq_chip intc_dev = {
@@ -103,13 +110,28 @@ static struct irq_chip intc_dev = {
103
110
.irq_mask_ack = intc_mask_ack ,
104
111
};
105
112
113
+ static unsigned int xintc_get_irq_local (struct xintc_irq_chip * irqc )
114
+ {
115
+ unsigned int irq = 0 ;
116
+ u32 hwirq ;
117
+
118
+ hwirq = xintc_read (irqc , IVR );
119
+ if (hwirq != -1U )
120
+ irq = irq_find_mapping (irqc -> root_domain , hwirq );
121
+
122
+ pr_debug ("irq-xilinx: hwirq=%d, irq=%d\n" , hwirq , irq );
123
+
124
+ return irq ;
125
+ }
126
+
106
127
unsigned int xintc_get_irq (void )
107
128
{
108
- unsigned int hwirq , irq = -1 ;
129
+ unsigned int irq = -1 ;
130
+ u32 hwirq ;
109
131
110
- hwirq = xintc_read (IVR );
132
+ hwirq = xintc_read (primary_intc , IVR );
111
133
if (hwirq != -1U )
112
- irq = irq_find_mapping (xintc_irqc -> root_domain , hwirq );
134
+ irq = irq_find_mapping (primary_intc -> root_domain , hwirq );
113
135
114
136
pr_debug ("irq-xilinx: hwirq=%d, irq=%d\n" , hwirq , irq );
115
137
@@ -118,15 +140,18 @@ unsigned int xintc_get_irq(void)
118
140
119
141
static int xintc_map (struct irq_domain * d , unsigned int irq , irq_hw_number_t hw )
120
142
{
121
- if (xintc_irqc -> intr_mask & (1 << hw )) {
143
+ struct xintc_irq_chip * irqc = d -> host_data ;
144
+
145
+ if (irqc -> intr_mask & BIT (hw )) {
122
146
irq_set_chip_and_handler_name (irq , & intc_dev ,
123
- handle_edge_irq , "edge" );
147
+ handle_edge_irq , "edge" );
124
148
irq_clear_status_flags (irq , IRQ_LEVEL );
125
149
} else {
126
150
irq_set_chip_and_handler_name (irq , & intc_dev ,
127
- handle_level_irq , "level" );
151
+ handle_level_irq , "level" );
128
152
irq_set_status_flags (irq , IRQ_LEVEL );
129
153
}
154
+ irq_set_chip_data (irq , irqc );
130
155
return 0 ;
131
156
}
132
157
@@ -138,12 +163,14 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
138
163
static void xil_intc_irq_handler (struct irq_desc * desc )
139
164
{
140
165
struct irq_chip * chip = irq_desc_get_chip (desc );
166
+ struct xintc_irq_chip * irqc ;
141
167
u32 pending ;
142
168
169
+ irqc = irq_data_get_irq_handler_data (& desc -> irq_data );
143
170
chained_irq_enter (chip , desc );
144
171
do {
145
- pending = xintc_get_irq ( );
146
- if (pending == -1U )
172
+ pending = xintc_get_irq_local ( irqc );
173
+ if (pending == 0 )
147
174
break ;
148
175
generic_handle_irq (pending );
149
176
} while (true);
@@ -153,28 +180,19 @@ static void xil_intc_irq_handler(struct irq_desc *desc)
153
180
static int __init xilinx_intc_of_init (struct device_node * intc ,
154
181
struct device_node * parent )
155
182
{
156
- u32 nr_irq ;
157
- int ret , irq ;
158
183
struct xintc_irq_chip * irqc ;
159
-
160
- if (xintc_irqc ) {
161
- pr_err ("irq-xilinx: Multiple instances aren't supported\n" );
162
- return - EINVAL ;
163
- }
184
+ int ret , irq ;
164
185
165
186
irqc = kzalloc (sizeof (* irqc ), GFP_KERNEL );
166
187
if (!irqc )
167
188
return - ENOMEM ;
168
-
169
- xintc_irqc = irqc ;
170
-
171
189
irqc -> base = of_iomap (intc , 0 );
172
190
BUG_ON (!irqc -> base );
173
191
174
- ret = of_property_read_u32 (intc , "xlnx,num-intr-inputs" , & nr_irq );
192
+ ret = of_property_read_u32 (intc , "xlnx,num-intr-inputs" , & irqc -> nr_irq );
175
193
if (ret < 0 ) {
176
194
pr_err ("irq-xilinx: unable to read xlnx,num-intr-inputs\n" );
177
- goto err_alloc ;
195
+ goto error ;
178
196
}
179
197
180
198
ret = of_property_read_u32 (intc , "xlnx,kind-of-intr" , & irqc -> intr_mask );
@@ -183,34 +201,34 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
183
201
irqc -> intr_mask = 0 ;
184
202
}
185
203
186
- if (irqc -> intr_mask >> nr_irq )
204
+ if (irqc -> intr_mask >> irqc -> nr_irq )
187
205
pr_warn ("irq-xilinx: mismatch in kind-of-intr param\n" );
188
206
189
207
pr_info ("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n" ,
190
- intc , nr_irq , irqc -> intr_mask );
208
+ intc , irqc -> nr_irq , irqc -> intr_mask );
191
209
192
210
193
211
/*
194
212
* Disable all external interrupts until they are
195
213
* explicity requested.
196
214
*/
197
- xintc_write (IER , 0 );
215
+ xintc_write (irqc , IER , 0 );
198
216
199
217
/* Acknowledge any pending interrupts just in case. */
200
- xintc_write (IAR , 0xffffffff );
218
+ xintc_write (irqc , IAR , 0xffffffff );
201
219
202
220
/* Turn on the Master Enable. */
203
- xintc_write (MER , MER_HIE | MER_ME );
204
- if (!( xintc_read (MER ) & (MER_HIE | MER_ME ) )) {
221
+ xintc_write (irqc , MER , MER_HIE | MER_ME );
222
+ if (xintc_read (irqc , MER ) != (MER_HIE | MER_ME )) {
205
223
static_branch_enable (& xintc_is_be );
206
- xintc_write (MER , MER_HIE | MER_ME );
224
+ xintc_write (irqc , MER , MER_HIE | MER_ME );
207
225
}
208
226
209
- irqc -> root_domain = irq_domain_add_linear (intc , nr_irq ,
227
+ irqc -> root_domain = irq_domain_add_linear (intc , irqc -> nr_irq ,
210
228
& xintc_irq_domain_ops , irqc );
211
229
if (!irqc -> root_domain ) {
212
230
pr_err ("irq-xilinx: Unable to create IRQ domain\n" );
213
- goto err_alloc ;
231
+ goto error ;
214
232
}
215
233
216
234
if (parent ) {
@@ -222,16 +240,17 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
222
240
} else {
223
241
pr_err ("irq-xilinx: interrupts property not in DT\n" );
224
242
ret = - EINVAL ;
225
- goto err_alloc ;
243
+ goto error ;
226
244
}
227
245
} else {
228
- irq_set_default_host (irqc -> root_domain );
246
+ primary_intc = irqc ;
247
+ irq_set_default_host (primary_intc -> root_domain );
229
248
}
230
249
231
250
return 0 ;
232
251
233
- err_alloc :
234
- xintc_irqc = NULL ;
252
+ error :
253
+ iounmap ( irqc -> base ) ;
235
254
kfree (irqc );
236
255
return ret ;
237
256
0 commit comments