@@ -1633,6 +1633,33 @@ static void __init iort_enable_acs(struct acpi_iort_node *iort_node)
}
}
}
+
+static acpi_status iort_match_host_bridge_callback(struct acpi_iort_node *node,
+ void *context)
+{
+ struct acpi_iort_root_complex *pci_rc;
+ struct pci_host_bridge *host_bridge = context;
+
+ pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+
+ return pci_domain_nr(host_bridge->bus) == pci_rc->pci_segment_number ?
+ AE_OK : AE_NOT_FOUND;
+}
+
+void iort_pci_host_bridge_setup(struct pci_host_bridge *host_bridge)
+{
+ struct acpi_iort_node *node;
+ struct acpi_iort_root_complex *pci_rc;
+
+ node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+ iort_match_host_bridge_callback, host_bridge);
+ if (!node)
+ return;
+
+ pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+ host_bridge->ats_supported = !!(pci_rc->ats_attribute &
+ ACPI_IORT_ATS_SUPPORTED);
+}
#else
static inline void iort_enable_acs(struct acpi_iort_node *iort_node) { }
#endif
@@ -6,6 +6,7 @@
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*/
+#include <linux/acpi_iort.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -917,6 +918,8 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL))
host_bridge->native_ltr = 0;
+ iort_pci_host_bridge_setup(host_bridge);
+
/*
* Evaluate the "PCI Boot Configuration" _DSM Function. If it
* exists and returns 0, we must preserve any PCI resource
@@ -10,6 +10,7 @@
#include <linux/acpi.h>
#include <linux/fwnode.h>
#include <linux/irqdomain.h>
+#include <linux/pci.h>
#define IORT_IRQ_MASK(irq) (irq & 0xffffffffULL)
#define IORT_IRQ_TRIGGER_MASK(irq) ((irq >> 32) & 0xffffffffULL)
@@ -55,4 +56,11 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
{ return 0; }
#endif
+#if defined(CONFIG_ACPI_IORT) && defined(CONFIG_PCI)
+void iort_pci_host_bridge_setup(struct pci_host_bridge *host_bridge);
+#else
+static inline
+void iort_pci_host_bridge_setup(struct pci_host_bridge *host_bridge) { }
+#endif
+
#endif /* __ACPI_IORT_H__ */