From e29fd6f4f0fcd07556a71aa74dbe17d37a36b818 Mon Sep 17 00:00:00 2001 From: Markuss Broks Date: Thu, 20 Aug 2026 22:12:07 +0300 Subject: [PATCH] iommu/exynos: fix TLB invalidation for no-block SysMMUs sysmmu_block() polls MMU_STATUS for the blocked state, which no-block hardware never reports, so on such SysMMUs it always fails, and both sysmmu_tlb_invalidate_entry() and sysmmu_tlb_invalidate_flpdcache() skip the invalidation entirely when blocking fails. On no-block hardware the invalidation registers are written with the MMU running; the vendor driver never blocks around invalidation. Do the same and write the invalidation directly. In the FLPD cache path no-block implies a v7+ SysMMU, hence the unconditional flush-all. Signed-off-by: Markuss Broks Acked-by: Marek Szyprowski Signed-off-by: Joerg Roedel --- drivers/iommu/exynos-iommu.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index a3a59d8a4cf1..29b27c7e400a 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -685,7 +685,14 @@ static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data, spin_lock_irqsave(&data->lock, flags); if (data->active && data->version >= MAKE_MMU_VER(3, 3)) { clk_enable(data->clk_master); - if (sysmmu_block(data)) { + /* + * No-block hardware accepts invalidation writes while the + * MMU is running; it is also v7+, so flush-all covers the + * FLPD cache. + */ + if (data->no_block) { + __sysmmu_tlb_invalidate(data); + } else if (sysmmu_block(data)) { if (data->version >= MAKE_MMU_VER(5, 0)) __sysmmu_tlb_invalidate(data); else @@ -721,7 +728,9 @@ static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data, if (MMU_MAJ_VER(data->version) == 2) num_inv = min_t(unsigned int, size / SPAGE_SIZE, 64); - if (sysmmu_block(data)) { + if (data->no_block) { + __sysmmu_tlb_invalidate_entry(data, iova, num_inv); + } else if (sysmmu_block(data)) { __sysmmu_tlb_invalidate_entry(data, iova, num_inv); sysmmu_unblock(data); }