Blob Blame History Raw
From 798740ac41231cfd3a1f18952a6ec15c2cde0416 Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Sat, 15 Jun 2019 10:23:59 +1000
Subject: [PATCH] arm64: PCI: Preserve firmware configuration when desired

Git-commit: 85dc04136e86680378546afb808357a58c06061c (Partial, Amazon Specific)
Patch-mainline: v5.3-rc1
References: SLE-9332 

If we must preserve the firmware resource assignments, claim the existing
resources rather than reassigning everything.

Link: https://lore.kernel.org/r/20190615002359.29577-4-benh@kernel.crashing.org
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

[Yousaf]: Whole series is folded in here
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
---
 arch/arm64/kernel/pci.c  |   50 +++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/pci-acpi.h |    1 
 2 files changed, 49 insertions(+), 2 deletions(-)

--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -179,6 +179,25 @@ static void pci_acpi_generic_release_inf
 	kfree(ri);
 }
 
+static bool is_amazon_graviton(void)
+{
+	static struct acpi_table_madt *madt;
+	acpi_status status;
+	bool ret = false;
+
+	status = acpi_get_table(ACPI_SIG_MADT, 0,
+			(struct acpi_table_header **)&madt);
+
+	if (ACPI_FAILURE(status) || !madt)
+               return ret;
+
+	ret = !memcmp(madt->header.oem_id, "AMAZON", ACPI_OEM_ID_SIZE);
+
+	acpi_put_table((struct acpi_table_header *)madt);
+
+	return ret;
+}
+
 /* Interface called from ACPI code to setup PCI host controller */
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 {
@@ -211,8 +230,35 @@ struct pci_bus *pci_acpi_scan_root(struc
 	if (!bus)
 		return NULL;
 
-	pci_bus_size_bridges(bus);
-	pci_bus_assign_resources(bus);
+	/* Only Evaluate _DSM Function #5 (PCI Boot Configuration function) on
+	 * Amazon Graviton.
+	 */
+	if (is_amazon_graviton()) {
+		union acpi_object *obj;
+
+		/*
+		 * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
+		 * exists and returns 0, we must preserve any PCI resource
+		 * assignments made by firmware for this host bridge.
+		 */
+		obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge),
+			&pci_acpi_dsm_guid, 1, IGNORE_PCI_BOOT_CONFIG_DSM, NULL);
+
+		if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
+			/* We must preserve the resource configuration, claim now */
+			pci_bus_claim_resources(bus);
+
+		/*
+		 * Assign whatever was left unassigned. If we didn't claim above,
+		 * this will reassign everything.
+		 */
+		pci_assign_unassigned_root_bus_resources(bus);
+
+		ACPI_FREE(obj);
+	} else {
+		pci_bus_size_bridges(bus);
+		pci_bus_assign_resources(bus);
+	}
 
 	list_for_each_entry(child, &bus->children, node)
 		pcie_bus_configure_settings(child);
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -106,6 +106,7 @@ static inline void acpiphp_check_host_br
 #endif
 
 extern const guid_t pci_acpi_dsm_guid;
+#define IGNORE_PCI_BOOT_CONFIG_DSM	0x05
 #define DEVICE_LABEL_DSM	0x07
 #define RESET_DELAY_DSM		0x08
 #define FUNCTION_DELAY_DSM	0x09