Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 324ba108 authored by Prem Mallappa's avatar Prem Mallappa Committed by Will Deacon
Browse files

iommu/arm-smmu: Fix write to GERRORN register



When acknowledging global errors, the GERRORN register should be written
with the original GERROR value so that active errors are toggled.

This patch fixed the driver to write the original GERROR value to
GERRORN, instead of an active error mask.

Signed-off-by: default avatarPrem Mallappa <pmallapp@broadcom.com>
[will: reworked use of active bits and fixed commit log]
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent fdc38967
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -1256,50 +1256,50 @@ static int arm_smmu_device_disable(struct arm_smmu_device *smmu);

static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev)
{
	u32 gerror, gerrorn;
	u32 gerror, gerrorn, active;
	struct arm_smmu_device *smmu = dev;

	gerror = readl_relaxed(smmu->base + ARM_SMMU_GERROR);
	gerrorn = readl_relaxed(smmu->base + ARM_SMMU_GERRORN);

	gerror ^= gerrorn;
	if (!(gerror & GERROR_ERR_MASK))
	active = gerror ^ gerrorn;
	if (!(active & GERROR_ERR_MASK))
		return IRQ_NONE; /* No errors pending */

	dev_warn(smmu->dev,
		 "unexpected global error reported (0x%08x), this could be serious\n",
		 gerror);
		 active);

	if (gerror & GERROR_SFM_ERR) {
	if (active & GERROR_SFM_ERR) {
		dev_err(smmu->dev, "device has entered Service Failure Mode!\n");
		arm_smmu_device_disable(smmu);
	}

	if (gerror & GERROR_MSI_GERROR_ABT_ERR)
	if (active & GERROR_MSI_GERROR_ABT_ERR)
		dev_warn(smmu->dev, "GERROR MSI write aborted\n");

	if (gerror & GERROR_MSI_PRIQ_ABT_ERR) {
	if (active & GERROR_MSI_PRIQ_ABT_ERR) {
		dev_warn(smmu->dev, "PRIQ MSI write aborted\n");
		arm_smmu_priq_handler(irq, smmu->dev);
	}

	if (gerror & GERROR_MSI_EVTQ_ABT_ERR) {
	if (active & GERROR_MSI_EVTQ_ABT_ERR) {
		dev_warn(smmu->dev, "EVTQ MSI write aborted\n");
		arm_smmu_evtq_handler(irq, smmu->dev);
	}

	if (gerror & GERROR_MSI_CMDQ_ABT_ERR) {
	if (active & GERROR_MSI_CMDQ_ABT_ERR) {
		dev_warn(smmu->dev, "CMDQ MSI write aborted\n");
		arm_smmu_cmdq_sync_handler(irq, smmu->dev);
	}

	if (gerror & GERROR_PRIQ_ABT_ERR)
	if (active & GERROR_PRIQ_ABT_ERR)
		dev_err(smmu->dev, "PRIQ write aborted -- events may have been lost\n");

	if (gerror & GERROR_EVTQ_ABT_ERR)
	if (active & GERROR_EVTQ_ABT_ERR)
		dev_err(smmu->dev, "EVTQ write aborted -- events may have been lost\n");

	if (gerror & GERROR_CMDQ_ERR)
	if (active & GERROR_CMDQ_ERR)
		arm_smmu_cmdq_skip_err(smmu);

	writel(gerror, smmu->base + ARM_SMMU_GERRORN);