Though qcom_adreno_smmu_impl is not used by ACPI boot right now, qcom_smmu_impl is already required at least to boot up Lenovo Flex 5G laptop. Let's check asl_compiler_id in IORT header to ensure we are running a QCOM SMMU and create qcom_smmu_impl for it. !np is used to check ACPI boot, because fwnode of SMMU device is a static allocation and thus has_acpi_companion() doesn't work here. Signed-off-by: Shawn Guo <shawn.guo@xxxxxxxxxx> --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index 98b3a1c2a181..5e8779483367 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -3,6 +3,7 @@ * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ +#include <linux/acpi_iort.h> #include <linux/adreno-smmu-priv.h> #include <linux/of_device.h> #include <linux/qcom_scm.h> @@ -339,10 +340,42 @@ static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { { } }; +#ifdef CONFIG_ACPI +static bool is_qcom_iort(struct arm_smmu_device *smmu) +{ + struct acpi_table_header *iort; + acpi_status status; + bool ret = false; + + status = acpi_get_table(ACPI_SIG_IORT, 0, &iort); + if (ACPI_FAILURE(status)) { + dev_err(smmu->dev, "failed to get IORT\n"); + goto done; + } + + if (strncmp(iort->asl_compiler_id, "QCOM", 4) == 0) { + ret = true; + goto done; + } + +done: + acpi_put_table(iort); + return ret; +} +#else +static bool is_qcom_iort(struct arm_smmu_device *smmu) +{ + return false; +} +#endif + struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu) { const struct device_node *np = smmu->dev->of_node; + if (!np && is_qcom_iort(smmu)) + return qcom_smmu_create(smmu, &qcom_smmu_impl); + if (of_match_node(qcom_smmu_impl_of_match, np)) return qcom_smmu_create(smmu, &qcom_smmu_impl); -- 2.17.1