summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Sethi <Varun.Sethi@freescale.com>2013-05-30 16:33:23 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-05-30 22:48:31 (GMT)
commitfded29b157442a8a1e438333fa438ca7e2174ee3 (patch)
treec3b6930df483bad02a26e14d4115a0d2f1b3dc2f
parenta87f76cb563a5acbea9bc46f4f676888cfa3f719 (diff)
downloadlinux-fsl-qoriq-fded29b157442a8a1e438333fa438ca7e2174ee3.tar.xz
[PATCH v3] iommu/fsl: Modify PAMU access violation handler.
Don't panic in case of an access violation, just disable the LIODN. Also, handle the hardware errata where access violation can be generated in case of an invalid LIODN. Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com> Change-Id: Ia6be04bf158cf6b722564c5ae690fba2b511d5f3 Reviewed-on: http://git.am.freescale.net:8181/2790 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Wood Scott-B07421 <scottwood@freescale.com> Reviewed-by: Yoder Stuart-B08248 <stuart.yoder@freescale.com> Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
-rw-r--r--drivers/iommu/fsl_pamu.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index e4be15a..1f69fd1 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -834,7 +834,7 @@ irqreturn_t pamu_av_isr(int irq, void *arg)
{
struct pamu_isr_data *data = arg;
phys_addr_t phys;
- unsigned int i, j;
+ unsigned int i, j, ret;
pr_emerg("fsl-pamu: access violation interrupt\n");
@@ -843,9 +843,12 @@ irqreturn_t pamu_av_isr(int irq, void *arg)
u32 pics = in_be32(p + PAMU_PICS);
if (pics & PAMU_ACCESS_VIOLATION_STAT) {
+ struct paace *paace;
+ u32 avs1 = in_be32(p + PAMU_AVS1);
+
pr_emerg("POES1=%08x\n", in_be32(p + PAMU_POES1));
pr_emerg("POES2=%08x\n", in_be32(p + PAMU_POES2));
- pr_emerg("AVS1=%08x\n", in_be32(p + PAMU_AVS1));
+ pr_emerg("AVS1=%08x\n", avs1);
pr_emerg("AVS2=%08x\n", in_be32(p + PAMU_AVS2));
pr_emerg("AVA=%016llx\n", make64(in_be32(p + PAMU_AVAH),
in_be32(p + PAMU_AVAL)));
@@ -864,12 +867,31 @@ irqreturn_t pamu_av_isr(int irq, void *arg)
for (j = 0; j < 4; j++)
pr_emerg("PAACE[%u]=%08x\n", j, in_be32(paace + j));
}
+
+ /* clear access violation condition */
+ out_be32((p + PAMU_AVS1), avs1 & PAMU_AV_MASK);
+ paace = pamu_get_ppaace(avs1 >> PAMU_AVS1_LIODN_SHIFT);
+ BUG_ON(!paace);
+ /* check if we got a violation for a disabled LIODN */
+ if (!get_bf(paace->addr_bitfields, PAACE_AF_V)) {
+ /*
+ * As per hardware erratum A-003638, access
+ * violation can be reported for a disabled
+ * LIODN. If we hit that condition, disable
+ * access violation reporting.
+ */
+ pr_emerg("Disabling access violation reporting\n");
+ pics &= ~PAMU_ACCESS_VIOLATION_ENABLE;
+ } else {
+ /* Disable the LIODN */
+ ret = pamu_disable_liodn(avs1 >> PAMU_AVS1_LIODN_SHIFT);
+ WARN_ON(ret);
+ pr_emerg("Disabling liodn %x\n", avs1 >> PAMU_AVS1_LIODN_SHIFT);
+ }
+ out_be32((p + PAMU_PICS), pics);
}
}
- panic("\n");
- /* NOTREACHED */
-
return IRQ_HANDLED;
}