@@ -6743,67 +6743,84 @@ static void pci_no_domains(void)
67436743}
67446744
67456745#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 );
67476748
6748- static int pci_get_new_domain_nr (void )
6749+ static void of_pci_reserve_static_domain_nr (void )
67496750{
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+ }
67516765}
67526766
67536767static int of_pci_bus_find_domain_nr (struct device * parent )
67546768{
6755- static int use_dt_domains = -1 ;
6756- int domain = -1 ;
6769+ static bool static_domains_reserved = false ;
6770+ int domain_nr ;
67576771
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+ }
67606790
67616791 /*
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.
67866796 */
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+ }
67986799
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 );
68006810}
68016811
68026812int pci_bus_find_domain_nr (struct pci_bus * bus , struct device * parent )
68036813{
68046814 return acpi_disabled ? of_pci_bus_find_domain_nr (parent ) :
68056815 acpi_pci_bus_find_domain_nr (bus );
68066816}
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+ }
68076824#endif
68086825
68096826/**
0 commit comments