@@ -421,24 +421,14 @@ static void __init gic_dist_init(void)
421
421
gic_write_irouter (affinity , base + GICD_IROUTER + i * 8 );
422
422
}
423
423
424
- static int gic_populate_rdist ( void )
424
+ static int gic_iterate_rdists ( int ( * fn )( struct redist_region * , void __iomem * ) )
425
425
{
426
- unsigned long mpidr = cpu_logical_map (smp_processor_id ());
427
- u64 typer ;
428
- u32 aff ;
426
+ int ret = - ENODEV ;
429
427
int i ;
430
428
431
- /*
432
- * Convert affinity to a 32bit value that can be matched to
433
- * GICR_TYPER bits [63:32].
434
- */
435
- aff = (MPIDR_AFFINITY_LEVEL (mpidr , 3 ) << 24 |
436
- MPIDR_AFFINITY_LEVEL (mpidr , 2 ) << 16 |
437
- MPIDR_AFFINITY_LEVEL (mpidr , 1 ) << 8 |
438
- MPIDR_AFFINITY_LEVEL (mpidr , 0 ));
439
-
440
429
for (i = 0 ; i < gic_data .nr_redist_regions ; i ++ ) {
441
430
void __iomem * ptr = gic_data .redist_regions [i ].redist_base ;
431
+ u64 typer ;
442
432
u32 reg ;
443
433
444
434
reg = readl_relaxed (ptr + GICR_PIDR2 ) & GIC_PIDR2_ARCH_MASK ;
@@ -450,15 +440,9 @@ static int gic_populate_rdist(void)
450
440
451
441
do {
452
442
typer = gic_read_typer (ptr + GICR_TYPER );
453
- if ((typer >> 32 ) == aff ) {
454
- u64 offset = ptr - gic_data .redist_regions [i ].redist_base ;
455
- gic_data_rdist_rd_base () = ptr ;
456
- gic_data_rdist ()-> phys_base = gic_data .redist_regions [i ].phys_base + offset ;
457
- pr_info ("CPU%d: found redistributor %lx region %d:%pa\n" ,
458
- smp_processor_id (), mpidr , i ,
459
- & gic_data_rdist ()-> phys_base );
443
+ ret = fn (gic_data .redist_regions + i , ptr );
444
+ if (!ret )
460
445
return 0 ;
461
- }
462
446
463
447
if (gic_data .redist_regions [i ].single_redist )
464
448
break ;
@@ -473,9 +457,50 @@ static int gic_populate_rdist(void)
473
457
} while (!(typer & GICR_TYPER_LAST ));
474
458
}
475
459
460
+ return ret ? - ENODEV : 0 ;
461
+ }
462
+
463
+ static int __gic_populate_rdist (struct redist_region * region , void __iomem * ptr )
464
+ {
465
+ unsigned long mpidr = cpu_logical_map (smp_processor_id ());
466
+ u64 typer ;
467
+ u32 aff ;
468
+
469
+ /*
470
+ * Convert affinity to a 32bit value that can be matched to
471
+ * GICR_TYPER bits [63:32].
472
+ */
473
+ aff = (MPIDR_AFFINITY_LEVEL (mpidr , 3 ) << 24 |
474
+ MPIDR_AFFINITY_LEVEL (mpidr , 2 ) << 16 |
475
+ MPIDR_AFFINITY_LEVEL (mpidr , 1 ) << 8 |
476
+ MPIDR_AFFINITY_LEVEL (mpidr , 0 ));
477
+
478
+ typer = gic_read_typer (ptr + GICR_TYPER );
479
+ if ((typer >> 32 ) == aff ) {
480
+ u64 offset = ptr - region -> redist_base ;
481
+ gic_data_rdist_rd_base () = ptr ;
482
+ gic_data_rdist ()-> phys_base = region -> phys_base + offset ;
483
+
484
+ pr_info ("CPU%d: found redistributor %lx region %d:%pa\n" ,
485
+ smp_processor_id (), mpidr ,
486
+ (int )(region - gic_data .redist_regions ),
487
+ & gic_data_rdist ()-> phys_base );
488
+ return 0 ;
489
+ }
490
+
491
+ /* Try next one */
492
+ return 1 ;
493
+ }
494
+
495
+ static int gic_populate_rdist (void )
496
+ {
497
+ if (gic_iterate_rdists (__gic_populate_rdist ) == 0 )
498
+ return 0 ;
499
+
476
500
/* We couldn't even deal with ourselves... */
477
501
WARN (true, "CPU%d: mpidr %lx has no re-distributor!\n" ,
478
- smp_processor_id (), mpidr );
502
+ smp_processor_id (),
503
+ (unsigned long )cpu_logical_map (smp_processor_id ()));
479
504
return - ENODEV ;
480
505
}
481
506
0 commit comments