|
@@ -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
|
|
|
|
|
|
/**
|