diff mbox series

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

Message ID 6e72111454a261be938b97a529294ef92b9408d0.1645106346.git.robin.murphy@arm.com (mailing list archive)
State New, archived
Headers show
Series perf: Arm SMMU PMU driver | expand

Commit Message

Robin Murphy Feb. 17, 2022, 2:24 p.m. UTC
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@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 mbox series

Patch

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;