Merge branches 'for-joerg/arm-smmu/smmu-v2' and 'for-joerg/arm-smmu/smmu-v3' into for-joerg/arm-smmu/updates
* for-joerg/arm-smmu/smmu-v2: Refactoring to allow for implementation-specific hooks in 'arm-smmu-impl.c' * for-joerg/arm-smmu/smmu-v3: Support for deferred TLB invalidation and batching of commands Rework ATC invalidation for ATS-enabled PCIe masters
This commit is contained in:
@@ -165,10 +165,32 @@ static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t size,
|
||||
}
|
||||
}
|
||||
|
||||
static const struct iommu_gather_ops qcom_gather_ops = {
|
||||
static void qcom_iommu_tlb_flush_walk(unsigned long iova, size_t size,
|
||||
size_t granule, void *cookie)
|
||||
{
|
||||
qcom_iommu_tlb_inv_range_nosync(iova, size, granule, false, cookie);
|
||||
qcom_iommu_tlb_sync(cookie);
|
||||
}
|
||||
|
||||
static void qcom_iommu_tlb_flush_leaf(unsigned long iova, size_t size,
|
||||
size_t granule, void *cookie)
|
||||
{
|
||||
qcom_iommu_tlb_inv_range_nosync(iova, size, granule, true, cookie);
|
||||
qcom_iommu_tlb_sync(cookie);
|
||||
}
|
||||
|
||||
static void qcom_iommu_tlb_add_page(struct iommu_iotlb_gather *gather,
|
||||
unsigned long iova, size_t granule,
|
||||
void *cookie)
|
||||
{
|
||||
qcom_iommu_tlb_inv_range_nosync(iova, granule, granule, true, cookie);
|
||||
}
|
||||
|
||||
static const struct iommu_flush_ops qcom_flush_ops = {
|
||||
.tlb_flush_all = qcom_iommu_tlb_inv_context,
|
||||
.tlb_add_flush = qcom_iommu_tlb_inv_range_nosync,
|
||||
.tlb_sync = qcom_iommu_tlb_sync,
|
||||
.tlb_flush_walk = qcom_iommu_tlb_flush_walk,
|
||||
.tlb_flush_leaf = qcom_iommu_tlb_flush_leaf,
|
||||
.tlb_add_page = qcom_iommu_tlb_add_page,
|
||||
};
|
||||
|
||||
static irqreturn_t qcom_iommu_fault(int irq, void *dev)
|
||||
@@ -216,7 +238,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
|
||||
.pgsize_bitmap = qcom_iommu_ops.pgsize_bitmap,
|
||||
.ias = 32,
|
||||
.oas = 40,
|
||||
.tlb = &qcom_gather_ops,
|
||||
.tlb = &qcom_flush_ops,
|
||||
.iommu_dev = qcom_iommu->dev,
|
||||
};
|
||||
|
||||
@@ -418,7 +440,7 @@ static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova,
|
||||
}
|
||||
|
||||
static size_t qcom_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
|
||||
size_t size)
|
||||
size_t size, struct iommu_iotlb_gather *gather)
|
||||
{
|
||||
size_t ret;
|
||||
unsigned long flags;
|
||||
@@ -435,14 +457,14 @@ static size_t qcom_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
|
||||
*/
|
||||
pm_runtime_get_sync(qcom_domain->iommu->dev);
|
||||
spin_lock_irqsave(&qcom_domain->pgtbl_lock, flags);
|
||||
ret = ops->unmap(ops, iova, size);
|
||||
ret = ops->unmap(ops, iova, size, gather);
|
||||
spin_unlock_irqrestore(&qcom_domain->pgtbl_lock, flags);
|
||||
pm_runtime_put_sync(qcom_domain->iommu->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void qcom_iommu_iotlb_sync(struct iommu_domain *domain)
|
||||
static void qcom_iommu_flush_iotlb_all(struct iommu_domain *domain)
|
||||
{
|
||||
struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
|
||||
struct io_pgtable *pgtable = container_of(qcom_domain->pgtbl_ops,
|
||||
@@ -455,6 +477,12 @@ static void qcom_iommu_iotlb_sync(struct iommu_domain *domain)
|
||||
pm_runtime_put_sync(qcom_domain->iommu->dev);
|
||||
}
|
||||
|
||||
static void qcom_iommu_iotlb_sync(struct iommu_domain *domain,
|
||||
struct iommu_iotlb_gather *gather)
|
||||
{
|
||||
qcom_iommu_flush_iotlb_all(domain);
|
||||
}
|
||||
|
||||
static phys_addr_t qcom_iommu_iova_to_phys(struct iommu_domain *domain,
|
||||
dma_addr_t iova)
|
||||
{
|
||||
@@ -582,7 +610,7 @@ static const struct iommu_ops qcom_iommu_ops = {
|
||||
.detach_dev = qcom_iommu_detach_dev,
|
||||
.map = qcom_iommu_map,
|
||||
.unmap = qcom_iommu_unmap,
|
||||
.flush_iotlb_all = qcom_iommu_iotlb_sync,
|
||||
.flush_iotlb_all = qcom_iommu_flush_iotlb_all,
|
||||
.iotlb_sync = qcom_iommu_iotlb_sync,
|
||||
.iova_to_phys = qcom_iommu_iova_to_phys,
|
||||
.add_device = qcom_iommu_add_device,
|
||||
|
Reference in New Issue
Block a user