@@ -4952,7 +4952,7 @@ static void __init __iomem *its_map_one(struct resource *res, int *err)
4952
4952
return NULL ;
4953
4953
}
4954
4954
4955
- static int its_init_domain (struct fwnode_handle * handle , struct its_node * its )
4955
+ static int its_init_domain (struct its_node * its )
4956
4956
{
4957
4957
struct irq_domain * inner_domain ;
4958
4958
struct msi_domain_info * info ;
@@ -4966,7 +4966,7 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
4966
4966
4967
4967
inner_domain = irq_domain_create_hierarchy (its_parent ,
4968
4968
its -> msi_domain_flags , 0 ,
4969
- handle , & its_domain_ops ,
4969
+ its -> fwnode_handle , & its_domain_ops ,
4970
4970
info );
4971
4971
if (!inner_domain ) {
4972
4972
kfree (info );
@@ -5017,8 +5017,7 @@ static int its_init_vpe_domain(void)
5017
5017
return 0 ;
5018
5018
}
5019
5019
5020
- static int __init its_compute_its_list_map (struct resource * res ,
5021
- void __iomem * its_base )
5020
+ static int __init its_compute_its_list_map (struct its_node * its )
5022
5021
{
5023
5022
int its_number ;
5024
5023
u32 ctlr ;
@@ -5032,91 +5031,66 @@ static int __init its_compute_its_list_map(struct resource *res,
5032
5031
its_number = find_first_zero_bit (& its_list_map , GICv4_ITS_LIST_MAX );
5033
5032
if (its_number >= GICv4_ITS_LIST_MAX ) {
5034
5033
pr_err ("ITS@%pa: No ITSList entry available!\n" ,
5035
- & res -> start );
5034
+ & its -> phys_base );
5036
5035
return - EINVAL ;
5037
5036
}
5038
5037
5039
- ctlr = readl_relaxed (its_base + GITS_CTLR );
5038
+ ctlr = readl_relaxed (its -> base + GITS_CTLR );
5040
5039
ctlr &= ~GITS_CTLR_ITS_NUMBER ;
5041
5040
ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT ;
5042
- writel_relaxed (ctlr , its_base + GITS_CTLR );
5043
- ctlr = readl_relaxed (its_base + GITS_CTLR );
5041
+ writel_relaxed (ctlr , its -> base + GITS_CTLR );
5042
+ ctlr = readl_relaxed (its -> base + GITS_CTLR );
5044
5043
if ((ctlr & GITS_CTLR_ITS_NUMBER ) != (its_number << GITS_CTLR_ITS_NUMBER_SHIFT )) {
5045
5044
its_number = ctlr & GITS_CTLR_ITS_NUMBER ;
5046
5045
its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT ;
5047
5046
}
5048
5047
5049
5048
if (test_and_set_bit (its_number , & its_list_map )) {
5050
5049
pr_err ("ITS@%pa: Duplicate ITSList entry %d\n" ,
5051
- & res -> start , its_number );
5050
+ & its -> phys_base , its_number );
5052
5051
return - EINVAL ;
5053
5052
}
5054
5053
5055
5054
return its_number ;
5056
5055
}
5057
5056
5058
- static int __init its_probe_one (struct resource * res ,
5059
- struct fwnode_handle * handle , int numa_node )
5057
+ static int __init its_probe_one (struct its_node * its )
5060
5058
{
5061
- struct its_node * its ;
5062
- void __iomem * its_base ;
5063
- u64 baser , tmp , typer ;
5059
+ u64 baser , tmp ;
5064
5060
struct page * page ;
5065
5061
u32 ctlr ;
5066
5062
int err ;
5067
5063
5068
- its_base = its_map_one (res , & err );
5069
- if (!its_base )
5070
- return err ;
5071
-
5072
- pr_info ("ITS %pR\n" , res );
5073
-
5074
- its = kzalloc (sizeof (* its ), GFP_KERNEL );
5075
- if (!its ) {
5076
- err = - ENOMEM ;
5077
- goto out_unmap ;
5078
- }
5079
-
5080
- raw_spin_lock_init (& its -> lock );
5081
- mutex_init (& its -> dev_alloc_lock );
5082
- INIT_LIST_HEAD (& its -> entry );
5083
- INIT_LIST_HEAD (& its -> its_device_list );
5084
- typer = gic_read_typer (its_base + GITS_TYPER );
5085
- its -> typer = typer ;
5086
- its -> base = its_base ;
5087
- its -> phys_base = res -> start ;
5088
5064
if (is_v4 (its )) {
5089
- if (!(typer & GITS_TYPER_VMOVP )) {
5090
- err = its_compute_its_list_map (res , its_base );
5065
+ if (!(its -> typer & GITS_TYPER_VMOVP )) {
5066
+ err = its_compute_its_list_map (its );
5091
5067
if (err < 0 )
5092
- goto out_free_its ;
5068
+ goto out ;
5093
5069
5094
5070
its -> list_nr = err ;
5095
5071
5096
5072
pr_info ("ITS@%pa: Using ITS number %d\n" ,
5097
- & res -> start , err );
5073
+ & its -> phys_base , err );
5098
5074
} else {
5099
- pr_info ("ITS@%pa: Single VMOVP capable\n" , & res -> start );
5075
+ pr_info ("ITS@%pa: Single VMOVP capable\n" , & its -> phys_base );
5100
5076
}
5101
5077
5102
5078
if (is_v4_1 (its )) {
5103
- u32 svpet = FIELD_GET (GITS_TYPER_SVPET , typer );
5079
+ u32 svpet = FIELD_GET (GITS_TYPER_SVPET , its -> typer );
5104
5080
5105
- its -> sgir_base = ioremap (res -> start + SZ_128K , SZ_64K );
5081
+ its -> sgir_base = ioremap (its -> phys_base + SZ_128K , SZ_64K );
5106
5082
if (!its -> sgir_base ) {
5107
5083
err = - ENOMEM ;
5108
- goto out_free_its ;
5084
+ goto out ;
5109
5085
}
5110
5086
5111
- its -> mpidr = readl_relaxed (its_base + GITS_MPIDR );
5087
+ its -> mpidr = readl_relaxed (its -> base + GITS_MPIDR );
5112
5088
5113
5089
pr_info ("ITS@%pa: Using GICv4.1 mode %08x %08x\n" ,
5114
- & res -> start , its -> mpidr , svpet );
5090
+ & its -> phys_base , its -> mpidr , svpet );
5115
5091
}
5116
5092
}
5117
5093
5118
- its -> numa_node = numa_node ;
5119
-
5120
5094
page = alloc_pages_node (its -> numa_node , GFP_KERNEL | __GFP_ZERO ,
5121
5095
get_order (ITS_CMD_QUEUE_SZ ));
5122
5096
if (!page ) {
@@ -5125,12 +5099,9 @@ static int __init its_probe_one(struct resource *res,
5125
5099
}
5126
5100
its -> cmd_base = (void * )page_address (page );
5127
5101
its -> cmd_write = its -> cmd_base ;
5128
- its -> fwnode_handle = handle ;
5129
5102
its -> get_msi_base = its_irq_get_msi_base ;
5130
5103
its -> msi_domain_flags = IRQ_DOMAIN_FLAG_ISOLATED_MSI ;
5131
5104
5132
- its_enable_quirks (its );
5133
-
5134
5105
err = its_alloc_tables (its );
5135
5106
if (err )
5136
5107
goto out_free_cmd ;
@@ -5174,7 +5145,7 @@ static int __init its_probe_one(struct resource *res,
5174
5145
ctlr |= GITS_CTLR_ImDe ;
5175
5146
writel_relaxed (ctlr , its -> base + GITS_CTLR );
5176
5147
5177
- err = its_init_domain (handle , its );
5148
+ err = its_init_domain (its );
5178
5149
if (err )
5179
5150
goto out_free_tables ;
5180
5151
@@ -5191,11 +5162,8 @@ static int __init its_probe_one(struct resource *res,
5191
5162
out_unmap_sgir :
5192
5163
if (its -> sgir_base )
5193
5164
iounmap (its -> sgir_base );
5194
- out_free_its :
5195
- kfree (its );
5196
- out_unmap :
5197
- iounmap (its_base );
5198
- pr_err ("ITS@%pa: failed probing (%d)\n" , & res -> start , err );
5165
+ out :
5166
+ pr_err ("ITS@%pa: failed probing (%d)\n" , & its -> phys_base , err );
5199
5167
return err ;
5200
5168
}
5201
5169
@@ -5356,10 +5324,53 @@ static const struct of_device_id its_device_id[] = {
5356
5324
{},
5357
5325
};
5358
5326
5327
+ static struct its_node __init * its_node_init (struct resource * res ,
5328
+ struct fwnode_handle * handle , int numa_node )
5329
+ {
5330
+ void __iomem * its_base ;
5331
+ struct its_node * its ;
5332
+ int err ;
5333
+
5334
+ its_base = its_map_one (res , & err );
5335
+ if (!its_base )
5336
+ return NULL ;
5337
+
5338
+ pr_info ("ITS %pR\n" , res );
5339
+
5340
+ its = kzalloc (sizeof (* its ), GFP_KERNEL );
5341
+ if (!its )
5342
+ goto out_unmap ;
5343
+
5344
+ raw_spin_lock_init (& its -> lock );
5345
+ mutex_init (& its -> dev_alloc_lock );
5346
+ INIT_LIST_HEAD (& its -> entry );
5347
+ INIT_LIST_HEAD (& its -> its_device_list );
5348
+
5349
+ its -> typer = gic_read_typer (its_base + GITS_TYPER );
5350
+ its -> base = its_base ;
5351
+ its -> phys_base = res -> start ;
5352
+
5353
+ its -> numa_node = numa_node ;
5354
+ its -> fwnode_handle = handle ;
5355
+
5356
+ return its ;
5357
+
5358
+ out_unmap :
5359
+ iounmap (its_base );
5360
+ return NULL ;
5361
+ }
5362
+
5363
+ static void its_node_destroy (struct its_node * its )
5364
+ {
5365
+ iounmap (its -> base );
5366
+ kfree (its );
5367
+ }
5368
+
5359
5369
static int __init its_of_probe (struct device_node * node )
5360
5370
{
5361
5371
struct device_node * np ;
5362
5372
struct resource res ;
5373
+ int err ;
5363
5374
5364
5375
/*
5365
5376
* Make sure *all* the ITS are reset before we probe any, as
@@ -5369,8 +5380,6 @@ static int __init its_of_probe(struct device_node *node)
5369
5380
*/
5370
5381
for (np = of_find_matching_node (node , its_device_id ); np ;
5371
5382
np = of_find_matching_node (np , its_device_id )) {
5372
- int err ;
5373
-
5374
5383
if (!of_device_is_available (np ) ||
5375
5384
!of_property_read_bool (np , "msi-controller" ) ||
5376
5385
of_address_to_resource (np , 0 , & res ))
@@ -5383,6 +5392,8 @@ static int __init its_of_probe(struct device_node *node)
5383
5392
5384
5393
for (np = of_find_matching_node (node , its_device_id ); np ;
5385
5394
np = of_find_matching_node (np , its_device_id )) {
5395
+ struct its_node * its ;
5396
+
5386
5397
if (!of_device_is_available (np ))
5387
5398
continue ;
5388
5399
if (!of_property_read_bool (np , "msi-controller" )) {
@@ -5396,7 +5407,17 @@ static int __init its_of_probe(struct device_node *node)
5396
5407
continue ;
5397
5408
}
5398
5409
5399
- its_probe_one (& res , & np -> fwnode , of_node_to_nid (np ));
5410
+
5411
+ its = its_node_init (& res , & np -> fwnode , of_node_to_nid (np ));
5412
+ if (!its )
5413
+ return - ENOMEM ;
5414
+
5415
+ its_enable_quirks (its );
5416
+ err = its_probe_one (its );
5417
+ if (err ) {
5418
+ its_node_destroy (its );
5419
+ return err ;
5420
+ }
5400
5421
}
5401
5422
return 0 ;
5402
5423
}
@@ -5508,6 +5529,7 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
5508
5529
{
5509
5530
struct acpi_madt_generic_translator * its_entry ;
5510
5531
struct fwnode_handle * dom_handle ;
5532
+ struct its_node * its ;
5511
5533
struct resource res ;
5512
5534
int err ;
5513
5535
@@ -5532,11 +5554,18 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
5532
5554
goto dom_err ;
5533
5555
}
5534
5556
5535
- err = its_probe_one (& res , dom_handle ,
5536
- acpi_get_its_numa_node (its_entry -> translation_id ));
5557
+ its = its_node_init (& res , dom_handle ,
5558
+ acpi_get_its_numa_node (its_entry -> translation_id ));
5559
+ if (!its ) {
5560
+ err = - ENOMEM ;
5561
+ goto node_err ;
5562
+ }
5563
+
5564
+ err = its_probe_one (its );
5537
5565
if (!err )
5538
5566
return 0 ;
5539
5567
5568
+ node_err :
5540
5569
iort_deregister_domain_token (its_entry -> translation_id );
5541
5570
dom_err :
5542
5571
irq_domain_free_fwnode (dom_handle );
0 commit comments