Skip to content

Commit 97dfad1

Browse files
rmurphy-armwilldeacon
authored andcommitted
iommu/arm-smmu: Account for PMU interrupts
In preparation for SMMUv2 PMU support, rejig our IRQ setup code to account for PMU interrupts as additional resources. We can simplify the whole flow by only storing the context IRQs, since the global IRQs are devres-managed and we never refer to them beyond the initial request. CC: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Link: https://lore.kernel.org/r/b2a40caaf1622eb35c555074a0d72f4f0513cff9.1645106346.git.robin.murphy@arm.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 8ddf4ef commit 97dfad1

2 files changed

Lines changed: 46 additions & 52 deletions

File tree

drivers/iommu/arm/arm-smmu/arm-smmu.c

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
807807
* Request context fault interrupt. Do this last to avoid the
808808
* handler seeing a half-initialised domain state.
809809
*/
810-
irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
810+
irq = smmu->irqs[cfg->irptndx];
811811

812812
if (smmu->impl && smmu->impl->context_fault)
813813
context_fault = smmu->impl->context_fault;
@@ -858,7 +858,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
858858
arm_smmu_write_context_bank(smmu, cfg->cbndx);
859859

860860
if (cfg->irptndx != ARM_SMMU_INVALID_IRPTNDX) {
861-
irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
861+
irq = smmu->irqs[cfg->irptndx];
862862
devm_free_irq(smmu->dev, irq, domain);
863863
}
864864

@@ -1951,8 +1951,8 @@ static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
19511951
return ret;
19521952
}
19531953

1954-
static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
1955-
struct arm_smmu_device *smmu)
1954+
static int arm_smmu_device_acpi_probe(struct arm_smmu_device *smmu,
1955+
u32 *global_irqs, u32 *pmu_irqs)
19561956
{
19571957
struct device *dev = smmu->dev;
19581958
struct acpi_iort_node *node =
@@ -1968,33 +1968,33 @@ static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
19681968
return ret;
19691969

19701970
/* Ignore the configuration access interrupt */
1971-
smmu->num_global_irqs = 1;
1971+
*global_irqs = 1;
1972+
*pmu_irqs = 0;
19721973

19731974
if (iort_smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK)
19741975
smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
19751976

19761977
return 0;
19771978
}
19781979
#else
1979-
static inline int arm_smmu_device_acpi_probe(struct platform_device *pdev,
1980-
struct arm_smmu_device *smmu)
1980+
static inline int arm_smmu_device_acpi_probe(struct arm_smmu_device *smmu,
1981+
u32 *global_irqs, u32 *pmu_irqs)
19811982
{
19821983
return -ENODEV;
19831984
}
19841985
#endif
19851986

1986-
static int arm_smmu_device_dt_probe(struct platform_device *pdev,
1987-
struct arm_smmu_device *smmu)
1987+
static int arm_smmu_device_dt_probe(struct arm_smmu_device *smmu,
1988+
u32 *global_irqs, u32 *pmu_irqs)
19881989
{
19891990
const struct arm_smmu_match_data *data;
1990-
struct device *dev = &pdev->dev;
1991+
struct device *dev = smmu->dev;
19911992
bool legacy_binding;
19921993

1993-
if (of_property_read_u32(dev->of_node, "#global-interrupts",
1994-
&smmu->num_global_irqs)) {
1995-
dev_err(dev, "missing #global-interrupts property\n");
1996-
return -ENODEV;
1997-
}
1994+
if (of_property_read_u32(dev->of_node, "#global-interrupts", global_irqs))
1995+
return dev_err_probe(dev, -ENODEV,
1996+
"missing #global-interrupts property\n");
1997+
*pmu_irqs = 0;
19981998

19991999
data = of_device_get_match_data(dev);
20002000
smmu->version = data->version;
@@ -2073,6 +2073,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
20732073
struct arm_smmu_device *smmu;
20742074
struct device *dev = &pdev->dev;
20752075
int num_irqs, i, err;
2076+
u32 global_irqs, pmu_irqs;
20762077
irqreturn_t (*global_fault)(int irq, void *dev);
20772078

20782079
smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
@@ -2083,10 +2084,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
20832084
smmu->dev = dev;
20842085

20852086
if (dev->of_node)
2086-
err = arm_smmu_device_dt_probe(pdev, smmu);
2087+
err = arm_smmu_device_dt_probe(smmu, &global_irqs, &pmu_irqs);
20872088
else
2088-
err = arm_smmu_device_acpi_probe(pdev, smmu);
2089-
2089+
err = arm_smmu_device_acpi_probe(smmu, &global_irqs, &pmu_irqs);
20902090
if (err)
20912091
return err;
20922092

@@ -2105,31 +2105,25 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
21052105
if (IS_ERR(smmu))
21062106
return PTR_ERR(smmu);
21072107

2108-
num_irqs = 0;
2109-
while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) {
2110-
num_irqs++;
2111-
if (num_irqs > smmu->num_global_irqs)
2112-
smmu->num_context_irqs++;
2113-
}
2108+
num_irqs = platform_irq_count(pdev);
21142109

2115-
if (!smmu->num_context_irqs) {
2116-
dev_err(dev, "found %d interrupts but expected at least %d\n",
2117-
num_irqs, smmu->num_global_irqs + 1);
2118-
return -ENODEV;
2119-
}
2110+
smmu->num_context_irqs = num_irqs - global_irqs - pmu_irqs;
2111+
if (smmu->num_context_irqs <= 0)
2112+
return dev_err_probe(dev, -ENODEV,
2113+
"found %d interrupts but expected at least %d\n",
2114+
num_irqs, global_irqs + pmu_irqs + 1);
21202115

2121-
smmu->irqs = devm_kcalloc(dev, num_irqs, sizeof(*smmu->irqs),
2122-
GFP_KERNEL);
2123-
if (!smmu->irqs) {
2124-
dev_err(dev, "failed to allocate %d irqs\n", num_irqs);
2125-
return -ENOMEM;
2126-
}
2116+
smmu->irqs = devm_kcalloc(dev, smmu->num_context_irqs,
2117+
sizeof(*smmu->irqs), GFP_KERNEL);
2118+
if (!smmu->irqs)
2119+
return dev_err_probe(dev, -ENOMEM, "failed to allocate %d irqs\n",
2120+
smmu->num_context_irqs);
21272121

2128-
for (i = 0; i < num_irqs; ++i) {
2129-
int irq = platform_get_irq(pdev, i);
2122+
for (i = 0; i < smmu->num_context_irqs; i++) {
2123+
int irq = platform_get_irq(pdev, global_irqs + pmu_irqs + i);
21302124

21312125
if (irq < 0)
2132-
return -ENODEV;
2126+
return irq;
21332127
smmu->irqs[i] = irq;
21342128
}
21352129

@@ -2165,17 +2159,18 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
21652159
else
21662160
global_fault = arm_smmu_global_fault;
21672161

2168-
for (i = 0; i < smmu->num_global_irqs; ++i) {
2169-
err = devm_request_irq(smmu->dev, smmu->irqs[i],
2170-
global_fault,
2171-
IRQF_SHARED,
2172-
"arm-smmu global fault",
2173-
smmu);
2174-
if (err) {
2175-
dev_err(dev, "failed to request global IRQ %d (%u)\n",
2176-
i, smmu->irqs[i]);
2177-
return err;
2178-
}
2162+
for (i = 0; i < global_irqs; i++) {
2163+
int irq = platform_get_irq(pdev, i);
2164+
2165+
if (irq < 0)
2166+
return irq;
2167+
2168+
err = devm_request_irq(dev, irq, global_fault, IRQF_SHARED,
2169+
"arm-smmu global fault", smmu);
2170+
if (err)
2171+
return dev_err_probe(dev, err,
2172+
"failed to request global IRQ %d (%u)\n",
2173+
i, irq);
21792174
}
21802175

21812176
err = iommu_device_sysfs_add(&smmu->iommu, smmu->dev, NULL,

drivers/iommu/arm/arm-smmu/arm-smmu.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,10 @@ struct arm_smmu_device {
318318
unsigned long pa_size;
319319
unsigned long pgsize_bitmap;
320320

321-
u32 num_global_irqs;
322-
u32 num_context_irqs;
321+
int num_context_irqs;
322+
int num_clks;
323323
unsigned int *irqs;
324324
struct clk_bulk_data *clks;
325-
int num_clks;
326325

327326
spinlock_t global_sync_lock;
328327

0 commit comments

Comments
 (0)