15
15
#include <linux/pci.h>
16
16
#include <linux/slab.h>
17
17
18
+ static int nr_pics ;
19
+
18
20
struct pch_msi_data {
19
21
struct mutex msi_map_lock ;
20
22
phys_addr_t doorbell ;
@@ -23,6 +25,8 @@ struct pch_msi_data {
23
25
unsigned long * msi_map ;
24
26
};
25
27
28
+ static struct fwnode_handle * pch_msi_handle [MAX_IO_PICS ];
29
+
26
30
static void pch_msi_mask_msi_irq (struct irq_data * d )
27
31
{
28
32
pci_msi_mask_irq (d );
@@ -154,12 +158,12 @@ static const struct irq_domain_ops pch_msi_middle_domain_ops = {
154
158
};
155
159
156
160
static int pch_msi_init_domains (struct pch_msi_data * priv ,
157
- struct device_node * node ,
158
- struct irq_domain * parent )
161
+ struct irq_domain * parent ,
162
+ struct fwnode_handle * domain_handle )
159
163
{
160
164
struct irq_domain * middle_domain , * msi_domain ;
161
165
162
- middle_domain = irq_domain_create_linear (of_node_to_fwnode ( node ) ,
166
+ middle_domain = irq_domain_create_linear (domain_handle ,
163
167
priv -> num_irqs ,
164
168
& pch_msi_middle_domain_ops ,
165
169
priv );
@@ -171,7 +175,7 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
171
175
middle_domain -> parent = parent ;
172
176
irq_domain_update_bus_token (middle_domain , DOMAIN_BUS_NEXUS );
173
177
174
- msi_domain = pci_msi_create_irq_domain (of_node_to_fwnode ( node ) ,
178
+ msi_domain = pci_msi_create_irq_domain (domain_handle ,
175
179
& pch_msi_domain_info ,
176
180
middle_domain );
177
181
if (!msi_domain ) {
@@ -183,68 +187,107 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
183
187
return 0 ;
184
188
}
185
189
186
- static int pch_msi_init (struct device_node * node ,
187
- struct device_node * parent )
190
+ static int pch_msi_init (phys_addr_t msg_address , int irq_base , int irq_count ,
191
+ struct irq_domain * parent_domain , struct fwnode_handle * domain_handle )
188
192
{
189
- struct pch_msi_data * priv ;
190
- struct irq_domain * parent_domain ;
191
- struct resource res ;
192
193
int ret ;
193
-
194
- parent_domain = irq_find_host (parent );
195
- if (!parent_domain ) {
196
- pr_err ("Failed to find the parent domain\n" );
197
- return - ENXIO ;
198
- }
194
+ struct pch_msi_data * priv ;
199
195
200
196
priv = kzalloc (sizeof (* priv ), GFP_KERNEL );
201
197
if (!priv )
202
198
return - ENOMEM ;
203
199
204
200
mutex_init (& priv -> msi_map_lock );
205
201
206
- ret = of_address_to_resource (node , 0 , & res );
207
- if (ret ) {
208
- pr_err ("Failed to allocate resource\n" );
209
- goto err_priv ;
210
- }
211
-
212
- priv -> doorbell = res .start ;
213
-
214
- if (of_property_read_u32 (node , "loongson,msi-base-vec" ,
215
- & priv -> irq_first )) {
216
- pr_err ("Unable to parse MSI vec base\n" );
217
- ret = - EINVAL ;
218
- goto err_priv ;
219
- }
220
-
221
- if (of_property_read_u32 (node , "loongson,msi-num-vecs" ,
222
- & priv -> num_irqs )) {
223
- pr_err ("Unable to parse MSI vec number\n" );
224
- ret = - EINVAL ;
225
- goto err_priv ;
226
- }
202
+ priv -> doorbell = msg_address ;
203
+ priv -> irq_first = irq_base ;
204
+ priv -> num_irqs = irq_count ;
227
205
228
206
priv -> msi_map = bitmap_zalloc (priv -> num_irqs , GFP_KERNEL );
229
- if (!priv -> msi_map ) {
230
- ret = - ENOMEM ;
207
+ if (!priv -> msi_map )
231
208
goto err_priv ;
232
- }
233
209
234
210
pr_debug ("Registering %d MSIs, starting at %d\n" ,
235
211
priv -> num_irqs , priv -> irq_first );
236
212
237
- ret = pch_msi_init_domains (priv , node , parent_domain );
213
+ ret = pch_msi_init_domains (priv , parent_domain , domain_handle );
238
214
if (ret )
239
215
goto err_map ;
240
216
217
+ pch_msi_handle [nr_pics ++ ] = domain_handle ;
241
218
return 0 ;
242
219
243
220
err_map :
244
221
bitmap_free (priv -> msi_map );
245
222
err_priv :
246
223
kfree (priv );
247
- return ret ;
224
+
225
+ return - EINVAL ;
226
+ }
227
+
228
+ #ifdef CONFIG_OF
229
+ static int pch_msi_of_init (struct device_node * node , struct device_node * parent )
230
+ {
231
+ int err ;
232
+ int irq_base , irq_count ;
233
+ struct resource res ;
234
+ struct irq_domain * parent_domain ;
235
+
236
+ parent_domain = irq_find_host (parent );
237
+ if (!parent_domain ) {
238
+ pr_err ("Failed to find the parent domain\n" );
239
+ return - ENXIO ;
240
+ }
241
+
242
+ if (of_address_to_resource (node , 0 , & res )) {
243
+ pr_err ("Failed to allocate resource\n" );
244
+ return - EINVAL ;
245
+ }
246
+
247
+ if (of_property_read_u32 (node , "loongson,msi-base-vec" , & irq_base )) {
248
+ pr_err ("Unable to parse MSI vec base\n" );
249
+ return - EINVAL ;
250
+ }
251
+
252
+ if (of_property_read_u32 (node , "loongson,msi-num-vecs" , & irq_count )) {
253
+ pr_err ("Unable to parse MSI vec number\n" );
254
+ return - EINVAL ;
255
+ }
256
+
257
+ err = pch_msi_init (res .start , irq_base , irq_count , parent_domain , of_node_to_fwnode (node ));
258
+ if (err < 0 )
259
+ return err ;
260
+
261
+ return 0 ;
248
262
}
249
263
250
- IRQCHIP_DECLARE (pch_msi , "loongson,pch-msi-1.0" , pch_msi_init );
264
+ IRQCHIP_DECLARE (pch_msi , "loongson,pch-msi-1.0" , pch_msi_of_init );
265
+ #endif
266
+
267
+ #ifdef CONFIG_ACPI
268
+ struct fwnode_handle * get_pch_msi_handle (int pci_segment )
269
+ {
270
+ int i ;
271
+
272
+ for (i = 0 ; i < MAX_IO_PICS ; i ++ ) {
273
+ if (msi_group [i ].pci_segment == pci_segment )
274
+ return pch_msi_handle [i ];
275
+ }
276
+ return NULL ;
277
+ }
278
+
279
+ int __init pch_msi_acpi_init (struct irq_domain * parent ,
280
+ struct acpi_madt_msi_pic * acpi_pchmsi )
281
+ {
282
+ int ret ;
283
+ struct fwnode_handle * domain_handle ;
284
+
285
+ domain_handle = irq_domain_alloc_fwnode ((phys_addr_t * )acpi_pchmsi );
286
+ ret = pch_msi_init (acpi_pchmsi -> msg_address , acpi_pchmsi -> start ,
287
+ acpi_pchmsi -> count , parent , domain_handle );
288
+ if (ret < 0 )
289
+ irq_domain_free_fwnode (domain_handle );
290
+
291
+ return ret ;
292
+ }
293
+ #endif
0 commit comments