iommu/arm-smmu: Tighten up global fault reporting
authorWill Deacon <will.deacon@arm.com>
Wed, 31 Jul 2013 18:21:26 +0000 (19:21 +0100)
committerJoerg Roedel <joro@8bytes.org>
Wed, 14 Aug 2013 10:09:14 +0000 (12:09 +0200)
On systems which use a single, combined irq line for the SMMU, context
faults may result in us spuriously reporting global faults with zero
status registers.

This patch fixes up the fsr checks in both the context and global fault
interrupt handlers, so that we only report the fault if the fsr
indicates something did indeed go awry.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Joerg Roedel <joro@8bytes.org>
drivers/iommu/arm-smmu.c

index da8af45634acf423ab30b7c2f32853583551a0fc..3a595bb5b8248af59d27d067cdae863536806521 100644 (file)
 #define FSR_IGN                                (FSR_AFF | FSR_ASF | FSR_TLBMCF |       \
                                         FSR_TLBLKF)
 #define FSR_FAULT                      (FSR_MULTI | FSR_SS | FSR_UUT |         \
-                                        FSR_EF | FSR_PF | FSR_TF)
+                                        FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
 
 #define FSYNR0_WNR                     (1 << 4)
 
@@ -590,6 +590,9 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
        void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
 
        gfsr = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
+       if (!gfsr)
+               return IRQ_NONE;
+
        gfsynr0 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR0);
        gfsynr1 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR1);
        gfsynr2 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR2);
@@ -601,7 +604,7 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
                gfsr, gfsynr0, gfsynr1, gfsynr2);
 
        writel(gfsr, gr0_base + ARM_SMMU_GR0_sGFSR);
-       return IRQ_NONE;
+       return IRQ_HANDLED;
 }
 
 static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)