41
41
42
42
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0)
43
43
#define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1)
44
+ #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2)
44
45
45
46
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
46
47
@@ -82,6 +83,7 @@ struct its_node {
82
83
u64 flags ;
83
84
u32 ite_size ;
84
85
u32 device_ids ;
86
+ int numa_node ;
85
87
};
86
88
87
89
#define ITS_ITT_ALIGN SZ_256
@@ -613,11 +615,23 @@ static void its_unmask_irq(struct irq_data *d)
613
615
static int its_set_affinity (struct irq_data * d , const struct cpumask * mask_val ,
614
616
bool force )
615
617
{
616
- unsigned int cpu = cpumask_any_and (mask_val , cpu_online_mask );
618
+ unsigned int cpu ;
619
+ const struct cpumask * cpu_mask = cpu_online_mask ;
617
620
struct its_device * its_dev = irq_data_get_irq_chip_data (d );
618
621
struct its_collection * target_col ;
619
622
u32 id = its_get_event_id (d );
620
623
624
+ /* lpi cannot be routed to a redistributor that is on a foreign node */
625
+ if (its_dev -> its -> flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144 ) {
626
+ if (its_dev -> its -> numa_node >= 0 ) {
627
+ cpu_mask = cpumask_of_node (its_dev -> its -> numa_node );
628
+ if (!cpumask_intersects (mask_val , cpu_mask ))
629
+ return - EINVAL ;
630
+ }
631
+ }
632
+
633
+ cpu = cpumask_any_and (mask_val , cpu_mask );
634
+
621
635
if (cpu >= nr_cpu_ids )
622
636
return - EINVAL ;
623
637
@@ -1101,6 +1115,16 @@ static void its_cpu_init_collection(void)
1101
1115
list_for_each_entry (its , & its_nodes , entry ) {
1102
1116
u64 target ;
1103
1117
1118
+ /* avoid cross node collections and its mapping */
1119
+ if (its -> flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144 ) {
1120
+ struct device_node * cpu_node ;
1121
+
1122
+ cpu_node = of_get_cpu_node (cpu , NULL );
1123
+ if (its -> numa_node != NUMA_NO_NODE &&
1124
+ its -> numa_node != of_node_to_nid (cpu_node ))
1125
+ continue ;
1126
+ }
1127
+
1104
1128
/*
1105
1129
* We now have to bind each collection to its target
1106
1130
* redistributor.
@@ -1351,9 +1375,14 @@ static void its_irq_domain_activate(struct irq_domain *domain,
1351
1375
{
1352
1376
struct its_device * its_dev = irq_data_get_irq_chip_data (d );
1353
1377
u32 event = its_get_event_id (d );
1378
+ const struct cpumask * cpu_mask = cpu_online_mask ;
1379
+
1380
+ /* get the cpu_mask of local node */
1381
+ if (its_dev -> its -> numa_node >= 0 )
1382
+ cpu_mask = cpumask_of_node (its_dev -> its -> numa_node );
1354
1383
1355
1384
/* Bind the LPI to the first possible CPU */
1356
- its_dev -> event_map .col_map [event ] = cpumask_first (cpu_online_mask );
1385
+ its_dev -> event_map .col_map [event ] = cpumask_first (cpu_mask );
1357
1386
1358
1387
/* Map the GIC IRQ and event to the device */
1359
1388
its_send_mapvi (its_dev , d -> hwirq , event );
@@ -1443,6 +1472,13 @@ static void __maybe_unused its_enable_quirk_cavium_22375(void *data)
1443
1472
its -> flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375 ;
1444
1473
}
1445
1474
1475
+ static void __maybe_unused its_enable_quirk_cavium_23144 (void * data )
1476
+ {
1477
+ struct its_node * its = data ;
1478
+
1479
+ its -> flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144 ;
1480
+ }
1481
+
1446
1482
static const struct gic_quirk its_quirks [] = {
1447
1483
#ifdef CONFIG_CAVIUM_ERRATUM_22375
1448
1484
{
@@ -1451,6 +1487,14 @@ static const struct gic_quirk its_quirks[] = {
1451
1487
.mask = 0xffff0fff ,
1452
1488
.init = its_enable_quirk_cavium_22375 ,
1453
1489
},
1490
+ #endif
1491
+ #ifdef CONFIG_CAVIUM_ERRATUM_23144
1492
+ {
1493
+ .desc = "ITS: Cavium erratum 23144" ,
1494
+ .iidr = 0xa100034c , /* ThunderX pass 1.x */
1495
+ .mask = 0xffff0fff ,
1496
+ .init = its_enable_quirk_cavium_23144 ,
1497
+ },
1454
1498
#endif
1455
1499
{
1456
1500
}
@@ -1514,6 +1558,7 @@ static int __init its_probe(struct device_node *node,
1514
1558
its -> base = its_base ;
1515
1559
its -> phys_base = res .start ;
1516
1560
its -> ite_size = ((readl_relaxed (its_base + GITS_TYPER ) >> 4 ) & 0xf ) + 1 ;
1561
+ its -> numa_node = of_node_to_nid (node );
1517
1562
1518
1563
its -> cmd_base = kzalloc (ITS_CMD_QUEUE_SZ , GFP_KERNEL );
1519
1564
if (!its -> cmd_base ) {
0 commit comments