/* * Device IOMMU generic operations */ static irqreturn_t iommu_fault_handler(int irq, void *data) { u32 stat, da; u32 *iopgd, *iopte; int err = -EIO; struct iommu *obj = data; if (!obj->refcount) return IRQ_NONE; eventfd_notification(obj); /* Dynamic loading TLB or PTE */ err = iommu_notify_event(obj, IOMMU_FAULT, data); if (err == NOTIFY_OK) return IRQ_HANDLED; if (!cpu_is_omap44xx()) clk_enable(obj->clk); stat = iommu_report_fault(obj, &da); if (!cpu_is_omap44xx()) clk_disable(obj->clk); if (!stat) return IRQ_HANDLED; iopgd = iopgd_offset(obj, da); if (!(*iopgd & IOPGD_TABLE)) { dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, da, iopgd, *iopgd); return IRQ_NONE; } iopte = iopte_offset(iopgd, da); dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n", __func__, da, iopgd, *iopgd, iopte, *iopte); return IRQ_NONE; }
/* * Device IOMMU generic operations */ static irqreturn_t iommu_fault_handler(int irq, void *data) { u32 stat, da; u32 *iopgd, *iopte; int err = -EIO; struct iommu *obj = data; if (!obj->refcount) return IRQ_NONE; /* Dynamic loading TLB or PTE */ if (obj->isr) err = obj->isr(obj); if (!err) return IRQ_HANDLED; clk_enable(obj->clk); stat = iommu_report_fault(obj, &da); clk_disable(obj->clk); if (!stat) return IRQ_HANDLED; iopgd = iopgd_offset(obj, da); if (!(*iopgd & IOPGD_TABLE)) { dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, da, iopgd, *iopgd); return IRQ_NONE; } iopte = iopte_offset(iopgd, da); dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n", __func__, da, iopgd, *iopgd, iopte, *iopte); return IRQ_NONE; }