diff options
author | Varun Sethi <Varun.Sethi@freescale.com> | 2013-05-30 16:33:23 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-05-30 22:48:31 (GMT) |
commit | fded29b157442a8a1e438333fa438ca7e2174ee3 (patch) | |
tree | c3b6930df483bad02a26e14d4115a0d2f1b3dc2f | |
parent | a87f76cb563a5acbea9bc46f4f676888cfa3f719 (diff) | |
download | linux-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.c | 32 |
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; } |