iommu/arm-smmu: add DT option to make address size faults fatal

Some hardware requires special fixups to recover from address size
faults.  Rather than applying the fixups add an option to just BUG since
address size faults are due to a fundamental programming error from
which we don't care about recovering anyways.

Change-Id: Ibb70e4ec00683562dae9f3239b286daa5deabd45
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
This commit is contained in:
Mitchel Humpherys 2015-01-30 14:58:52 -08:00 committed by David Keitel
parent cde5a4ec7b
commit a0f2281e2b
2 changed files with 15 additions and 0 deletions

View file

@ -79,6 +79,12 @@ conditions.
- qcom,errata-ctx-fault-hang : Enable workaround for a context fault hang
hardware errata.
- qcom,fatal-asf : Enable BUG_ON for address size faults. Some hardware
requires special fixups to recover from address size
faults. Rather than applying the fixups just BUG since
address size faults are due to a fundamental programming
error from which we don't care about recovering anyways.
- clocks : List of clocks to be used during SMMU register access. See
Documentation/devicetree/bindings/clock/clock-bindings.txt
for information about the format. For each clock specified

View file

@ -428,6 +428,7 @@ struct arm_smmu_device {
#define ARM_SMMU_OPT_REGISTER_SAVE (1 << 3)
#define ARM_SMMU_OPT_SKIP_INIT (1 << 4)
#define ARM_SMMU_OPT_ERRATA_CTX_FAULT_HANG (1 << 5)
#define ARM_SMMU_OPT_FATAL_ASF (1 << 6)
u32 options;
enum arm_smmu_arch_version version;
@ -498,6 +499,7 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ ARM_SMMU_OPT_REGISTER_SAVE, "qcom,register-save" },
{ ARM_SMMU_OPT_SKIP_INIT, "qcom,skip-init" },
{ ARM_SMMU_OPT_ERRATA_CTX_FAULT_HANG, "qcom,errata-ctx-fault-hang" },
{ ARM_SMMU_OPT_FATAL_ASF, "qcom,fatal-asf" },
{ 0, NULL},
};
@ -839,6 +841,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
void __iomem *cb_base;
bool ctx_hang_errata =
smmu->options & ARM_SMMU_OPT_ERRATA_CTX_FAULT_HANG;
bool fatal_asf = smmu->options & ARM_SMMU_OPT_FATAL_ASF;
arm_smmu_enable_clocks(smmu);
@ -855,6 +858,12 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
"Unexpected context fault (fsr 0x%x)\n",
fsr);
if (fatal_asf && (fsr & FSR_ASF)) {
dev_err(smmu->dev,
"Took an address size fault. Refusing to recover.\n");
BUG();
}
fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
flags = fsynr & FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ;