ACPI/IORT: Update SMMUv3 DeviceID support
authorRobin Murphy <robin.murphy@arm.com>
Wed, 28 Sep 2022 19:21:26 +0000 (20:21 +0100)
committerWill Deacon <will@kernel.org>
Mon, 7 Nov 2022 15:39:03 +0000 (15:39 +0000)
IORT E.e now allows SMMUv3 nodes to describe the DeviceID for MSIs
independently of wired GSIVs, where the previous oddly-restrictive
definition meant that an SMMU without PRI support had to provide a
DeviceID even if it didn't support MSIs either. Support this, with
the usual temporary flag definition while the real one is making
its way through ACPICA.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Link: https://lore.kernel.org/r/4b3e2ead4f392d1a47a7528da119d57918e5d806.1664392886.git.robin.murphy@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/acpi/arm64/iort.c

index 8059baf..38fb849 100644 (file)
@@ -402,6 +402,10 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
        return NULL;
 }
 
+#ifndef ACPI_IORT_SMMU_V3_DEVICEID_VALID
+#define ACPI_IORT_SMMU_V3_DEVICEID_VALID (1 << 4)
+#endif
+
 static int iort_get_id_mapping_index(struct acpi_iort_node *node)
 {
        struct acpi_iort_smmu_v3 *smmu;
@@ -418,12 +422,16 @@ static int iort_get_id_mapping_index(struct acpi_iort_node *node)
 
                smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
                /*
-                * ID mapping index is only ignored if all interrupts are
-                * GSIV based
+                * Until IORT E.e (node rev. 5), the ID mapping index was
+                * defined to be valid unless all interrupts are GSIV-based.
                 */
-               if (smmu->event_gsiv && smmu->pri_gsiv && smmu->gerr_gsiv
-                   && smmu->sync_gsiv)
+               if (node->revision < 5) {
+                       if (smmu->event_gsiv && smmu->pri_gsiv &&
+                           smmu->gerr_gsiv && smmu->sync_gsiv)
+                               return -EINVAL;
+               } else if (!(smmu->flags & ACPI_IORT_SMMU_V3_DEVICEID_VALID)) {
                        return -EINVAL;
+               }
 
                if (smmu->id_mapping_index >= node->mapping_count) {
                        pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n",