diff options
-rw-r--r-- | arch/arm64/kernel/pci.c | 22 | ||||
-rw-r--r-- | drivers/pci/pci.c | 49 |
2 files changed, 49 insertions, 22 deletions
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index ce5836c14ec1..6f93c24ca801 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -46,25 +46,3 @@ int pcibios_add_device(struct pci_dev *dev) return 0; } - - -#ifdef CONFIG_PCI_DOMAINS_GENERIC -static bool dt_domain_found = false; - -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) -{ - int domain = of_get_pci_domain_nr(parent->of_node); - - if (domain >= 0) { - dt_domain_found = true; - } else if (dt_domain_found == true) { - dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n", - parent->of_node->full_name); - return; - } else { - domain = pci_get_new_domain_nr(); - } - - bus->domain_nr = domain; -} -#endif diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cab05f31223f..c419554d0b4b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -10,6 +10,8 @@ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/init.h> +#include <linux/of.h> +#include <linux/of_pci.h> #include <linux/pci.h> #include <linux/pm.h> #include <linux/slab.h> @@ -4439,6 +4441,53 @@ int pci_get_new_domain_nr(void) { return atomic_inc_return(&__domain_nr); } + +#ifdef CONFIG_PCI_DOMAINS_GENERIC +void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) +{ + static int use_dt_domains = -1; + int domain = of_get_pci_domain_nr(parent->of_node); + + /* + * Check DT domain and use_dt_domains values. + * + * If DT domain property is valid (domain >= 0) and + * use_dt_domains != 0, the DT assignment is valid since this means + * we have not previously allocated a domain number by using + * pci_get_new_domain_nr(); we should also update use_dt_domains to + * 1, to indicate that we have just assigned a domain number from + * DT. + * + * If DT domain property value is not valid (ie domain < 0), and we + * have not previously assigned a domain number from DT + * (use_dt_domains != 1) we should assign a domain number by + * using the: + * + * pci_get_new_domain_nr() + * + * API and update the use_dt_domains value to keep track of method we + * are using to assign domain numbers (use_dt_domains = 0). + * + * All other combinations imply we have a platform that is trying + * to mix domain numbers obtained from DT and pci_get_new_domain_nr(), + * which is a recipe for domain mishandling and it is prevented by + * invalidating the domain value (domain = -1) and printing a + * corresponding error. + */ + if (domain >= 0 && use_dt_domains) { + use_dt_domains = 1; + } else if (domain < 0 && use_dt_domains != 1) { + use_dt_domains = 0; + domain = pci_get_new_domain_nr(); + } else { + dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n", + parent->of_node->full_name); + domain = -1; + } + + bus->domain_nr = domain; +} +#endif #endif /** |