[PATCH 2/6] acpi/iort: Register SMMUv2 PMU interrupts

Robin Murphy robin.murphy at arm.com
Thu Feb 17 06:24:16 PST 2022


In preparation for SMMUv2 PMU support, make sure the PMU IRQs are
parsed out of IORT and registered somewhere the SMMU driver can find
them. Without making massively invasive changes there aren't many ways
to achieve this; inserting them into the SMMU's resource list between
the global and context IRQs is easy enough to cope with in the driver,
and offers the path of least resistance for the DT binding too.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/acpi/arm64/iort.c             | 18 ++++++++++++++----
 drivers/iommu/arm/arm-smmu/arm-smmu.c |  2 +-
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3b23fb775ac4..175397913be1 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1277,10 +1277,10 @@ static int __init arm_smmu_count_resources(struct acpi_iort_node *node)
 	 * configuration access interrupt.
 	 *
 	 * MMIO address and global fault interrupt resources are always
-	 * present so add them to the context interrupt count as a static
-	 * value.
+	 * present so add them to the context + PMU interrupt count as a
+	 * static value.
 	 */
-	return smmu->context_interrupt_count + 2;
+	return smmu->pmu_interrupt_count + smmu->context_interrupt_count + 2;
 }
 
 static void __init arm_smmu_init_resources(struct resource *res,
@@ -1288,7 +1288,7 @@ static void __init arm_smmu_init_resources(struct resource *res,
 {
 	struct acpi_iort_smmu *smmu;
 	int i, hw_irq, trigger, num_res = 0;
-	u64 *ctx_irq, *glb_irq;
+	u64 *ctx_irq, *glb_irq, *pmu_irq;
 
 	/* Retrieve SMMU specific data */
 	smmu = (struct acpi_iort_smmu *)node->node_data;
@@ -1306,6 +1306,16 @@ static void __init arm_smmu_init_resources(struct resource *res,
 	acpi_iort_register_irq(hw_irq, "arm-smmu-global", trigger,
 				     &res[num_res++]);
 
+	/* PMU IRQs */
+	pmu_irq = ACPI_ADD_PTR(u64, node, smmu->pmu_interrupt_offset);
+	for (i = 0; i < smmu->pmu_interrupt_count; i++) {
+		hw_irq = IORT_IRQ_MASK(pmu_irq[i]);
+		trigger = IORT_IRQ_TRIGGER_MASK(pmu_irq[i]);
+
+		acpi_iort_register_irq(hw_irq, "arm-smmu-pmu", trigger,
+				       &res[num_res++]);
+	}
+
 	/* Context IRQs */
 	ctx_irq = ACPI_ADD_PTR(u64, node, smmu->context_interrupt_offset);
 	for (i = 0; i < smmu->context_interrupt_count; i++) {
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index e50fcf37af58..cbfe4cc914f0 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1969,7 +1969,7 @@ static int arm_smmu_device_acpi_probe(struct arm_smmu_device *smmu,
 
 	/* Ignore the configuration access interrupt */
 	*global_irqs = 1;
-	*pmu_irqs = 0;
+	*pmu_irqs = iort_smmu->pmu_interrupt_count;
 
 	if (iort_smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK)
 		smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
-- 
2.28.0.dirty




More information about the linux-arm-kernel mailing list