summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLiam Mark <lmark@codeaurora.org>2016-12-20 11:34:04 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-04 14:19:17 -0800
commitc4e398bbc8aa40b09010bb3b01b167b7936e2549 (patch)
tree93935cb4e320eb08399cd174af3324d9f549a9f2 /drivers
parent5ade64f1b176fb3ec68d778e69b2b8182717c630 (diff)
iommu/io-pgtable-arm: Set page table coherency
Currently the coherency of an iommu's page table is dictated by the coherency of the iommu device. Support being able to configure iommu page tables as being coherent or not. Change-Id: I311d535b673cc476edb431145bfdb85015361ab7 Signed-off-by: Liam Mark <lmark@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/io-pgtable-arm.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 3f9825a9addb..0d057ca92972 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -290,6 +290,16 @@ static dma_addr_t __arm_lpae_dma_addr(void *pages)
return (dma_addr_t)virt_to_phys(pages);
}
+static inline void pgtable_dma_sync_single_for_device(
+ struct io_pgtable_cfg *cfg,
+ dma_addr_t addr, size_t size,
+ enum dma_data_direction dir)
+{
+ if (!(cfg->quirks & IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT))
+ dma_sync_single_for_device(cfg->iommu_dev, addr, size,
+ dir);
+}
+
static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
struct io_pgtable_cfg *cfg,
void *cookie)
@@ -340,7 +350,7 @@ static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
*ptep = pte;
if (!selftest_running)
- dma_sync_single_for_device(cfg->iommu_dev,
+ pgtable_dma_sync_single_for_device(cfg,
__arm_lpae_dma_addr(ptep),
sizeof(pte), DMA_TO_DEVICE);
}
@@ -415,7 +425,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
if (lvl == MAP_STATE_LVL) {
if (ms->pgtable)
- dma_sync_single_for_device(cfg->iommu_dev,
+ pgtable_dma_sync_single_for_device(cfg,
__arm_lpae_dma_addr(ms->pte_start),
ms->num_pte * sizeof(*ptep),
DMA_TO_DEVICE);
@@ -433,7 +443,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
* mapping. Flush out the previous page mappings.
*/
if (ms->pgtable)
- dma_sync_single_for_device(cfg->iommu_dev,
+ pgtable_dma_sync_single_for_device(cfg,
__arm_lpae_dma_addr(ms->pte_start),
ms->num_pte * sizeof(*ptep),
DMA_TO_DEVICE);
@@ -603,7 +613,7 @@ static int arm_lpae_map_sg(struct io_pgtable_ops *ops, unsigned long iova,
}
if (ms.pgtable)
- dma_sync_single_for_device(cfg->iommu_dev,
+ pgtable_dma_sync_single_for_device(cfg,
__arm_lpae_dma_addr(ms.pte_start),
ms.num_pte * sizeof(*ms.pte_start),
DMA_TO_DEVICE);
@@ -753,7 +763,7 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
table += tl_offset;
memset(table, 0, table_len);
- dma_sync_single_for_device(cfg->iommu_dev,
+ pgtable_dma_sync_single_for_device(cfg,
__arm_lpae_dma_addr(table),
table_len, DMA_TO_DEVICE);
@@ -994,7 +1004,7 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
return NULL;
/* TCR */
- if (cfg->iommu_dev && cfg->iommu_dev->archdata.dma_coherent)
+ if (cfg->quirks & IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT)
reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);