@@ -250,6 +250,85 @@ IRQCHIP_DECLARE(andes, "andestech,cpu-intc", riscv_intc_init);
250
250
251
251
#ifdef CONFIG_ACPI
252
252
253
+ struct rintc_data {
254
+ union {
255
+ u32 ext_intc_id ;
256
+ struct {
257
+ u32 context_id : 16 ,
258
+ reserved : 8 ,
259
+ aplic_plic_id : 8 ;
260
+ };
261
+ };
262
+ unsigned long hart_id ;
263
+ u64 imsic_addr ;
264
+ u32 imsic_size ;
265
+ };
266
+
267
+ static u32 nr_rintc ;
268
+ static struct rintc_data * rintc_acpi_data [NR_CPUS ];
269
+
270
+ #define for_each_matching_plic (_plic_id ) \
271
+ unsigned int _plic; \
272
+ \
273
+ for (_plic = 0; _plic < nr_rintc; _plic++) \
274
+ if (rintc_acpi_data[_plic]->aplic_plic_id != _plic_id) \
275
+ continue; \
276
+ else
277
+
278
+ unsigned int acpi_rintc_get_plic_nr_contexts (unsigned int plic_id )
279
+ {
280
+ unsigned int nctx = 0 ;
281
+
282
+ for_each_matching_plic (plic_id )
283
+ nctx ++ ;
284
+
285
+ return nctx ;
286
+ }
287
+
288
+ static struct rintc_data * get_plic_context (unsigned int plic_id , unsigned int ctxt_idx )
289
+ {
290
+ unsigned int ctxt = 0 ;
291
+
292
+ for_each_matching_plic (plic_id ) {
293
+ if (ctxt == ctxt_idx )
294
+ return rintc_acpi_data [_plic ];
295
+
296
+ ctxt ++ ;
297
+ }
298
+
299
+ return NULL ;
300
+ }
301
+
302
+ unsigned long acpi_rintc_ext_parent_to_hartid (unsigned int plic_id , unsigned int ctxt_idx )
303
+ {
304
+ struct rintc_data * data = get_plic_context (plic_id , ctxt_idx );
305
+
306
+ return data ? data -> hart_id : INVALID_HARTID ;
307
+ }
308
+
309
+ unsigned int acpi_rintc_get_plic_context (unsigned int plic_id , unsigned int ctxt_idx )
310
+ {
311
+ struct rintc_data * data = get_plic_context (plic_id , ctxt_idx );
312
+
313
+ return data ? data -> context_id : INVALID_CONTEXT ;
314
+ }
315
+
316
+ unsigned long acpi_rintc_index_to_hartid (u32 index )
317
+ {
318
+ return index >= nr_rintc ? INVALID_HARTID : rintc_acpi_data [index ]-> hart_id ;
319
+ }
320
+
321
+ int acpi_rintc_get_imsic_mmio_info (u32 index , struct resource * res )
322
+ {
323
+ if (index >= nr_rintc )
324
+ return -1 ;
325
+
326
+ res -> start = rintc_acpi_data [index ]-> imsic_addr ;
327
+ res -> end = res -> start + rintc_acpi_data [index ]-> imsic_size - 1 ;
328
+ res -> flags = IORESOURCE_MEM ;
329
+ return 0 ;
330
+ }
331
+
253
332
static int __init riscv_intc_acpi_init (union acpi_subtable_headers * header ,
254
333
const unsigned long end )
255
334
{
@@ -258,6 +337,15 @@ static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
258
337
int rc ;
259
338
260
339
rintc = (struct acpi_madt_rintc * )header ;
340
+ rintc_acpi_data [nr_rintc ] = kzalloc (sizeof (* rintc_acpi_data [0 ]), GFP_KERNEL );
341
+ if (!rintc_acpi_data [nr_rintc ])
342
+ return - ENOMEM ;
343
+
344
+ rintc_acpi_data [nr_rintc ]-> ext_intc_id = rintc -> ext_intc_id ;
345
+ rintc_acpi_data [nr_rintc ]-> hart_id = rintc -> hart_id ;
346
+ rintc_acpi_data [nr_rintc ]-> imsic_addr = rintc -> imsic_addr ;
347
+ rintc_acpi_data [nr_rintc ]-> imsic_size = rintc -> imsic_size ;
348
+ nr_rintc ++ ;
261
349
262
350
/*
263
351
* The ACPI MADT will have one INTC for each CPU (or HART)
@@ -277,6 +365,8 @@ static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
277
365
rc = riscv_intc_init_common (fn , & riscv_intc_chip );
278
366
if (rc )
279
367
irq_domain_free_fwnode (fn );
368
+ else
369
+ acpi_set_irq_model (ACPI_IRQ_MODEL_RINTC , riscv_acpi_get_gsi_domain_id );
280
370
281
371
return rc ;
282
372
}
0 commit comments