summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2013-07-31 20:21:26 +0200
committerJoerg Roedel <joro@8bytes.org>2013-08-14 12:09:14 +0200
commitadaba320916d246af56821a1aab81a715091e7e5 (patch)
tree434d23ba1dc9f068150b7657d23ee66d9b2ce5cb /drivers
parentiommu/arm-smmu: Remove broken big-endian check (diff)
downloadlinux-adaba320916d246af56821a1aab81a715091e7e5.tar.xz
linux-adaba320916d246af56821a1aab81a715091e7e5.zip
iommu/arm-smmu: Tighten up global fault reporting
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/arm-smmu.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index da8af45634ac..3a595bb5b824 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -305,7 +305,7 @@
#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)