diff options
Diffstat (limited to 'arch/arm/plat-omap/iommu.c')
-rw-r--r-- | arch/arm/plat-omap/iommu.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index bc094dbacee6..a202a2ce6e3d 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c | |||
@@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj) | |||
370 | } | 370 | } |
371 | EXPORT_SYMBOL_GPL(flush_iotlb_all); | 371 | EXPORT_SYMBOL_GPL(flush_iotlb_all); |
372 | 372 | ||
373 | /** | ||
374 | * iommu_set_twl - enable/disable table walking logic | ||
375 | * @obj: target iommu | ||
376 | * @on: enable/disable | ||
377 | * | ||
378 | * Function used to enable/disable TWL. If one wants to work | ||
379 | * exclusively with locked TLB entries and receive notifications | ||
380 | * for TLB miss then call this function to disable TWL. | ||
381 | */ | ||
382 | void iommu_set_twl(struct iommu *obj, bool on) | ||
383 | { | ||
384 | clk_enable(obj->clk); | ||
385 | arch_iommu->set_twl(obj, on); | ||
386 | clk_disable(obj->clk); | ||
387 | } | ||
388 | EXPORT_SYMBOL_GPL(iommu_set_twl); | ||
389 | |||
373 | #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) | 390 | #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) |
374 | 391 | ||
375 | ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) | 392 | ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) |
@@ -653,7 +670,7 @@ void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte) | |||
653 | if (!*iopgd) | 670 | if (!*iopgd) |
654 | goto out; | 671 | goto out; |
655 | 672 | ||
656 | if (*iopgd & IOPGD_TABLE) | 673 | if (iopgd_is_table(*iopgd)) |
657 | iopte = iopte_offset(iopgd, da); | 674 | iopte = iopte_offset(iopgd, da); |
658 | out: | 675 | out: |
659 | *ppgd = iopgd; | 676 | *ppgd = iopgd; |
@@ -670,7 +687,7 @@ static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da) | |||
670 | if (!*iopgd) | 687 | if (!*iopgd) |
671 | return 0; | 688 | return 0; |
672 | 689 | ||
673 | if (*iopgd & IOPGD_TABLE) { | 690 | if (iopgd_is_table(*iopgd)) { |
674 | int i; | 691 | int i; |
675 | u32 *iopte = iopte_offset(iopgd, da); | 692 | u32 *iopte = iopte_offset(iopgd, da); |
676 | 693 | ||
@@ -745,7 +762,7 @@ static void iopgtable_clear_entry_all(struct iommu *obj) | |||
745 | if (!*iopgd) | 762 | if (!*iopgd) |
746 | continue; | 763 | continue; |
747 | 764 | ||
748 | if (*iopgd & IOPGD_TABLE) | 765 | if (iopgd_is_table(*iopgd)) |
749 | iopte_free(iopte_offset(iopgd, 0)); | 766 | iopte_free(iopte_offset(iopgd, 0)); |
750 | 767 | ||
751 | *iopgd = 0; | 768 | *iopgd = 0; |
@@ -783,9 +800,11 @@ static irqreturn_t iommu_fault_handler(int irq, void *data) | |||
783 | if (!stat) | 800 | if (!stat) |
784 | return IRQ_HANDLED; | 801 | return IRQ_HANDLED; |
785 | 802 | ||
803 | iommu_disable(obj); | ||
804 | |||
786 | iopgd = iopgd_offset(obj, da); | 805 | iopgd = iopgd_offset(obj, da); |
787 | 806 | ||
788 | if (!(*iopgd & IOPGD_TABLE)) { | 807 | if (!iopgd_is_table(*iopgd)) { |
789 | dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, | 808 | dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, |
790 | da, iopgd, *iopgd); | 809 | da, iopgd, *iopgd); |
791 | return IRQ_NONE; | 810 | return IRQ_NONE; |