diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 49 |
1 files changed, 49 insertions, 0 deletions
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 @@ | |||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/of.h> | ||
14 | #include <linux/of_pci.h> | ||
13 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
14 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
15 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
@@ -4439,6 +4441,53 @@ int pci_get_new_domain_nr(void) | |||
4439 | { | 4441 | { |
4440 | return atomic_inc_return(&__domain_nr); | 4442 | return atomic_inc_return(&__domain_nr); |
4441 | } | 4443 | } |
4444 | |||
4445 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
4446 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | ||
4447 | { | ||
4448 | static int use_dt_domains = -1; | ||
4449 | int domain = of_get_pci_domain_nr(parent->of_node); | ||
4450 | |||
4451 | /* | ||
4452 | * Check DT domain and use_dt_domains values. | ||
4453 | * | ||
4454 | * If DT domain property is valid (domain >= 0) and | ||
4455 | * use_dt_domains != 0, the DT assignment is valid since this means | ||
4456 | * we have not previously allocated a domain number by using | ||
4457 | * pci_get_new_domain_nr(); we should also update use_dt_domains to | ||
4458 | * 1, to indicate that we have just assigned a domain number from | ||
4459 | * DT. | ||
4460 | * | ||
4461 | * If DT domain property value is not valid (ie domain < 0), and we | ||
4462 | * have not previously assigned a domain number from DT | ||
4463 | * (use_dt_domains != 1) we should assign a domain number by | ||
4464 | * using the: | ||
4465 | * | ||
4466 | * pci_get_new_domain_nr() | ||
4467 | * | ||
4468 | * API and update the use_dt_domains value to keep track of method we | ||
4469 | * are using to assign domain numbers (use_dt_domains = 0). | ||
4470 | * | ||
4471 | * All other combinations imply we have a platform that is trying | ||
4472 | * to mix domain numbers obtained from DT and pci_get_new_domain_nr(), | ||
4473 | * which is a recipe for domain mishandling and it is prevented by | ||
4474 | * invalidating the domain value (domain = -1) and printing a | ||
4475 | * corresponding error. | ||
4476 | */ | ||
4477 | if (domain >= 0 && use_dt_domains) { | ||
4478 | use_dt_domains = 1; | ||
4479 | } else if (domain < 0 && use_dt_domains != 1) { | ||
4480 | use_dt_domains = 0; | ||
4481 | domain = pci_get_new_domain_nr(); | ||
4482 | } else { | ||
4483 | dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n", | ||
4484 | parent->of_node->full_name); | ||
4485 | domain = -1; | ||
4486 | } | ||
4487 | |||
4488 | bus->domain_nr = domain; | ||
4489 | } | ||
4490 | #endif | ||
4442 | #endif | 4491 | #endif |
4443 | 4492 | ||
4444 | /** | 4493 | /** |