|
10 | 10 | #include <linux/kernel.h>
|
11 | 11 | #include <linux/delay.h>
|
12 | 12 | #include <linux/init.h>
|
| 13 | +#include <linux/of.h> |
| 14 | +#include <linux/of_pci.h> |
13 | 15 | #include <linux/pci.h>
|
14 | 16 | #include <linux/pm.h>
|
15 | 17 | #include <linux/slab.h>
|
@@ -4439,6 +4441,53 @@ int pci_get_new_domain_nr(void)
|
4439 | 4441 | {
|
4440 | 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 | 4491 | #endif
|
4443 | 4492 |
|
4444 | 4493 | /**
|
|
0 commit comments