void clear_fault_bits(struct vtd_iommu *iommu)
{
- u64 val;
unsigned long flags;
spin_lock_irqsave(&iommu->register_lock, flags);
- val = dmar_readq(iommu->reg, cap_fault_reg_offset(iommu->cap) + 8);
- dmar_writeq(iommu->reg, cap_fault_reg_offset(iommu->cap) + 8, val);
+
+ if ( dmar_readl(iommu->reg, DMAR_FSTS_REG) & DMA_FSTS_PPF )
+ {
+ unsigned int reg = cap_fault_reg_offset(iommu->cap);
+ unsigned int end = reg + cap_num_fault_regs(iommu->cap);
+
+ do {
+ dmar_writel(iommu->reg, reg + 12, DMA_FRCD_F);
+ reg += PRIMARY_FAULT_REG_LEN;
+ } while ( reg < end );
+ }
+
dmar_writel(iommu->reg, DMAR_FSTS_REG, DMA_FSTS_FAULTS);
+
spin_unlock_irqrestore(&iommu->register_lock, flags);
}
#define DMA_FSTS_IQE ((u64)1 << 4)
#define DMA_FSTS_ICE ((u64)1 << 5)
#define DMA_FSTS_ITE ((u64)1 << 6)
-#define DMA_FSTS_FAULTS DMA_FSTS_PFO | DMA_FSTS_PPF | DMA_FSTS_AFO | DMA_FSTS_APF | DMA_FSTS_IQE | DMA_FSTS_ICE | DMA_FSTS_ITE
+#define DMA_FSTS_FAULTS (DMA_FSTS_PFO | DMA_FSTS_AFO | DMA_FSTS_APF | \
+ DMA_FSTS_IQE | DMA_FSTS_ICE | DMA_FSTS_ITE)
#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff)
/* FRCD_REG, 32 bits access */