@@ -4856,6 +4856,38 @@ static struct syscore_ops its_syscore_ops = {
4856
4856
.resume = its_restore_enable ,
4857
4857
};
4858
4858
4859
+ static void __init __iomem * its_map_one (struct resource * res , int * err )
4860
+ {
4861
+ void __iomem * its_base ;
4862
+ u32 val ;
4863
+
4864
+ its_base = ioremap (res -> start , SZ_64K );
4865
+ if (!its_base ) {
4866
+ pr_warn ("ITS@%pa: Unable to map ITS registers\n" , & res -> start );
4867
+ * err = - ENOMEM ;
4868
+ return NULL ;
4869
+ }
4870
+
4871
+ val = readl_relaxed (its_base + GITS_PIDR2 ) & GIC_PIDR2_ARCH_MASK ;
4872
+ if (val != 0x30 && val != 0x40 ) {
4873
+ pr_warn ("ITS@%pa: No ITS detected, giving up\n" , & res -> start );
4874
+ * err = - ENODEV ;
4875
+ goto out_unmap ;
4876
+ }
4877
+
4878
+ * err = its_force_quiescent (its_base );
4879
+ if (* err ) {
4880
+ pr_warn ("ITS@%pa: Failed to quiesce, giving up\n" , & res -> start );
4881
+ goto out_unmap ;
4882
+ }
4883
+
4884
+ return its_base ;
4885
+
4886
+ out_unmap :
4887
+ iounmap (its_base );
4888
+ return NULL ;
4889
+ }
4890
+
4859
4891
static int its_init_domain (struct fwnode_handle * handle , struct its_node * its )
4860
4892
{
4861
4893
struct irq_domain * inner_domain ;
@@ -4963,29 +4995,14 @@ static int __init its_probe_one(struct resource *res,
4963
4995
{
4964
4996
struct its_node * its ;
4965
4997
void __iomem * its_base ;
4966
- u32 val , ctlr ;
4967
4998
u64 baser , tmp , typer ;
4968
4999
struct page * page ;
5000
+ u32 ctlr ;
4969
5001
int err ;
4970
5002
4971
- its_base = ioremap (res -> start , SZ_64K );
4972
- if (!its_base ) {
4973
- pr_warn ("ITS@%pa: Unable to map ITS registers\n" , & res -> start );
4974
- return - ENOMEM ;
4975
- }
4976
-
4977
- val = readl_relaxed (its_base + GITS_PIDR2 ) & GIC_PIDR2_ARCH_MASK ;
4978
- if (val != 0x30 && val != 0x40 ) {
4979
- pr_warn ("ITS@%pa: No ITS detected, giving up\n" , & res -> start );
4980
- err = - ENODEV ;
4981
- goto out_unmap ;
4982
- }
4983
-
4984
- err = its_force_quiescent (its_base );
4985
- if (err ) {
4986
- pr_warn ("ITS@%pa: Failed to quiesce, giving up\n" , & res -> start );
4987
- goto out_unmap ;
4988
- }
5003
+ its_base = its_map_one (res , & err );
5004
+ if (!its_base )
5005
+ return err ;
4989
5006
4990
5007
pr_info ("ITS %pR\n" , res );
4991
5008
@@ -5249,6 +5266,23 @@ static int its_cpu_memreserve_lpi(unsigned int cpu)
5249
5266
return ret ;
5250
5267
}
5251
5268
5269
+ /* Mark all the BASER registers as invalid before they get reprogrammed */
5270
+ static int __init its_reset_one (struct resource * res )
5271
+ {
5272
+ void __iomem * its_base ;
5273
+ int err , i ;
5274
+
5275
+ its_base = its_map_one (res , & err );
5276
+ if (!its_base )
5277
+ return err ;
5278
+
5279
+ for (i = 0 ; i < GITS_BASER_NR_REGS ; i ++ )
5280
+ gits_write_baser (0 , its_base + GITS_BASER + (i << 3 ));
5281
+
5282
+ iounmap (its_base );
5283
+ return 0 ;
5284
+ }
5285
+
5252
5286
static const struct of_device_id its_device_id [] = {
5253
5287
{ .compatible = "arm,gic-v3-its" , },
5254
5288
{},
@@ -5259,6 +5293,26 @@ static int __init its_of_probe(struct device_node *node)
5259
5293
struct device_node * np ;
5260
5294
struct resource res ;
5261
5295
5296
+ /*
5297
+ * Make sure *all* the ITS are reset before we probe any, as
5298
+ * they may be sharing memory. If any of the ITS fails to
5299
+ * reset, don't even try to go any further, as this could
5300
+ * result in something even worse.
5301
+ */
5302
+ for (np = of_find_matching_node (node , its_device_id ); np ;
5303
+ np = of_find_matching_node (np , its_device_id )) {
5304
+ int err ;
5305
+
5306
+ if (!of_device_is_available (np ) ||
5307
+ !of_property_read_bool (np , "msi-controller" ) ||
5308
+ of_address_to_resource (np , 0 , & res ))
5309
+ continue ;
5310
+
5311
+ err = its_reset_one (& res );
5312
+ if (err )
5313
+ return err ;
5314
+ }
5315
+
5262
5316
for (np = of_find_matching_node (node , its_device_id ); np ;
5263
5317
np = of_find_matching_node (np , its_device_id )) {
5264
5318
if (!of_device_is_available (np ))
@@ -5421,11 +5475,35 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
5421
5475
return err ;
5422
5476
}
5423
5477
5478
+ static int __init its_acpi_reset (union acpi_subtable_headers * header ,
5479
+ const unsigned long end )
5480
+ {
5481
+ struct acpi_madt_generic_translator * its_entry ;
5482
+ struct resource res ;
5483
+
5484
+ its_entry = (struct acpi_madt_generic_translator * )header ;
5485
+ res = (struct resource ) {
5486
+ .start = its_entry -> base_address ,
5487
+ .end = its_entry -> base_address + ACPI_GICV3_ITS_MEM_SIZE - 1 ,
5488
+ .flags = IORESOURCE_MEM ,
5489
+ };
5490
+
5491
+ return its_reset_one (& res );
5492
+ }
5493
+
5424
5494
static void __init its_acpi_probe (void )
5425
5495
{
5426
5496
acpi_table_parse_srat_its ();
5427
- acpi_table_parse_madt (ACPI_MADT_TYPE_GENERIC_TRANSLATOR ,
5428
- gic_acpi_parse_madt_its , 0 );
5497
+ /*
5498
+ * Make sure *all* the ITS are reset before we probe any, as
5499
+ * they may be sharing memory. If any of the ITS fails to
5500
+ * reset, don't even try to go any further, as this could
5501
+ * result in something even worse.
5502
+ */
5503
+ if (acpi_table_parse_madt (ACPI_MADT_TYPE_GENERIC_TRANSLATOR ,
5504
+ its_acpi_reset , 0 ) > 0 )
5505
+ acpi_table_parse_madt (ACPI_MADT_TYPE_GENERIC_TRANSLATOR ,
5506
+ gic_acpi_parse_madt_its , 0 );
5429
5507
acpi_its_srat_maps_free ();
5430
5508
}
5431
5509
#else
0 commit comments