| From fb38428413dca3783e24ec5ee456e013c4addb40 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 25 Oct 2022 18:54:12 +0200 |
| Subject: iommu/sun50i: Consider all fault sources for reset |
| |
| From: Jernej Skrabec <jernej.skrabec@gmail.com> |
| |
| [ Upstream commit cef20703e2b2276aaa402ec5a65ec9a09963b83e ] |
| |
| We have to reset masters for all faults - permissions, L1 fault or L2 |
| fault. Currently it's done only for permissions. If other type of fault |
| happens, master is in locked up state. Fix that by really considering |
| all fault sources. |
| |
| Fixes: 4100b8c229b3 ("iommu: Add Allwinner H6 IOMMU driver") |
| Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com> |
| Link: https://lore.kernel.org/r/20221025165415.307591-3-jernej.skrabec@gmail.com |
| Signed-off-by: Joerg Roedel <jroedel@suse.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/iommu/sun50i-iommu.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c |
| index c777882d0ec2..38d1069cf383 100644 |
| --- a/drivers/iommu/sun50i-iommu.c |
| +++ b/drivers/iommu/sun50i-iommu.c |
| @@ -869,8 +869,8 @@ static phys_addr_t sun50i_iommu_handle_perm_irq(struct sun50i_iommu *iommu) |
| |
| static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id) |
| { |
| + u32 status, l1_status, l2_status, resets; |
| struct sun50i_iommu *iommu = dev_id; |
| - u32 status; |
| |
| spin_lock(&iommu->iommu_lock); |
| |
| @@ -880,6 +880,9 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id) |
| return IRQ_NONE; |
| } |
| |
| + l1_status = iommu_read(iommu, IOMMU_L1PG_INT_REG); |
| + l2_status = iommu_read(iommu, IOMMU_L2PG_INT_REG); |
| + |
| if (status & IOMMU_INT_INVALID_L2PG) |
| sun50i_iommu_handle_pt_irq(iommu, |
| IOMMU_INT_ERR_ADDR_L2_REG, |
| @@ -893,7 +896,8 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id) |
| |
| iommu_write(iommu, IOMMU_INT_CLR_REG, status); |
| |
| - iommu_write(iommu, IOMMU_RESET_REG, ~status); |
| + resets = (status | l1_status | l2_status) & IOMMU_INT_MASTER_MASK; |
| + iommu_write(iommu, IOMMU_RESET_REG, ~resets); |
| iommu_write(iommu, IOMMU_RESET_REG, IOMMU_RESET_RELEASE_ALL); |
| |
| spin_unlock(&iommu->iommu_lock); |
| -- |
| 2.35.1 |
| |