@@ -6743,67 +6743,84 @@ static void pci_no_domains(void)
6743
6743
}
6744
6744
6745
6745
#ifdef CONFIG_PCI_DOMAINS_GENERIC
6746
- static atomic_t __domain_nr = ATOMIC_INIT (-1 );
6746
+ static DEFINE_IDA (pci_domain_nr_static_ida );
6747
+ static DEFINE_IDA (pci_domain_nr_dynamic_ida );
6747
6748
6748
- static int pci_get_new_domain_nr (void )
6749
+ static void of_pci_reserve_static_domain_nr (void )
6749
6750
{
6750
- return atomic_inc_return (& __domain_nr );
6751
+ struct device_node * np ;
6752
+ int domain_nr ;
6753
+
6754
+ for_each_node_by_type (np , "pci" ) {
6755
+ domain_nr = of_get_pci_domain_nr (np );
6756
+ if (domain_nr < 0 )
6757
+ continue ;
6758
+ /*
6759
+ * Permanently allocate domain_nr in dynamic_ida
6760
+ * to prevent it from dynamic allocation.
6761
+ */
6762
+ ida_alloc_range (& pci_domain_nr_dynamic_ida ,
6763
+ domain_nr , domain_nr , GFP_KERNEL );
6764
+ }
6751
6765
}
6752
6766
6753
6767
static int of_pci_bus_find_domain_nr (struct device * parent )
6754
6768
{
6755
- static int use_dt_domains = -1 ;
6756
- int domain = -1 ;
6769
+ static bool static_domains_reserved = false ;
6770
+ int domain_nr ;
6757
6771
6758
- if (parent )
6759
- domain = of_get_pci_domain_nr (parent -> of_node );
6772
+ /* On the first call scan device tree for static allocations. */
6773
+ if (!static_domains_reserved ) {
6774
+ of_pci_reserve_static_domain_nr ();
6775
+ static_domains_reserved = true;
6776
+ }
6777
+
6778
+ if (parent ) {
6779
+ /*
6780
+ * If domain is in DT, allocate it in static IDA. This
6781
+ * prevents duplicate static allocations in case of errors
6782
+ * in DT.
6783
+ */
6784
+ domain_nr = of_get_pci_domain_nr (parent -> of_node );
6785
+ if (domain_nr >= 0 )
6786
+ return ida_alloc_range (& pci_domain_nr_static_ida ,
6787
+ domain_nr , domain_nr ,
6788
+ GFP_KERNEL );
6789
+ }
6760
6790
6761
6791
/*
6762
- * Check DT domain and use_dt_domains values.
6763
- *
6764
- * If DT domain property is valid (domain >= 0) and
6765
- * use_dt_domains != 0, the DT assignment is valid since this means
6766
- * we have not previously allocated a domain number by using
6767
- * pci_get_new_domain_nr(); we should also update use_dt_domains to
6768
- * 1, to indicate that we have just assigned a domain number from
6769
- * DT.
6770
- *
6771
- * If DT domain property value is not valid (ie domain < 0), and we
6772
- * have not previously assigned a domain number from DT
6773
- * (use_dt_domains != 1) we should assign a domain number by
6774
- * using the:
6775
- *
6776
- * pci_get_new_domain_nr()
6777
- *
6778
- * API and update the use_dt_domains value to keep track of method we
6779
- * are using to assign domain numbers (use_dt_domains = 0).
6780
- *
6781
- * All other combinations imply we have a platform that is trying
6782
- * to mix domain numbers obtained from DT and pci_get_new_domain_nr(),
6783
- * which is a recipe for domain mishandling and it is prevented by
6784
- * invalidating the domain value (domain = -1) and printing a
6785
- * corresponding error.
6792
+ * If domain was not specified in DT, choose a free ID from dynamic
6793
+ * allocations. All domain numbers from DT are permanently in
6794
+ * dynamic allocations to prevent assigning them to other DT nodes
6795
+ * without static domain.
6786
6796
*/
6787
- if (domain >= 0 && use_dt_domains ) {
6788
- use_dt_domains = 1 ;
6789
- } else if (domain < 0 && use_dt_domains != 1 ) {
6790
- use_dt_domains = 0 ;
6791
- domain = pci_get_new_domain_nr ();
6792
- } else {
6793
- if (parent )
6794
- pr_err ("Node %pOF has " , parent -> of_node );
6795
- pr_err ("Inconsistent \"linux,pci-domain\" property in DT\n" );
6796
- domain = -1 ;
6797
- }
6797
+ return ida_alloc (& pci_domain_nr_dynamic_ida , GFP_KERNEL );
6798
+ }
6798
6799
6799
- return domain ;
6800
+ static void of_pci_bus_release_domain_nr (struct pci_bus * bus , struct device * parent )
6801
+ {
6802
+ if (bus -> domain_nr < 0 )
6803
+ return ;
6804
+
6805
+ /* Release domain from IDA where it was allocated. */
6806
+ if (of_get_pci_domain_nr (parent -> of_node ) == bus -> domain_nr )
6807
+ ida_free (& pci_domain_nr_static_ida , bus -> domain_nr );
6808
+ else
6809
+ ida_free (& pci_domain_nr_dynamic_ida , bus -> domain_nr );
6800
6810
}
6801
6811
6802
6812
int pci_bus_find_domain_nr (struct pci_bus * bus , struct device * parent )
6803
6813
{
6804
6814
return acpi_disabled ? of_pci_bus_find_domain_nr (parent ) :
6805
6815
acpi_pci_bus_find_domain_nr (bus );
6806
6816
}
6817
+
6818
+ void pci_bus_release_domain_nr (struct pci_bus * bus , struct device * parent )
6819
+ {
6820
+ if (!acpi_disabled )
6821
+ return ;
6822
+ of_pci_bus_release_domain_nr (bus , parent );
6823
+ }
6807
6824
#endif
6808
6825
6809
6826
/**
0 commit comments