mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
iommu: io-pgtable-fast: Use the DMA APIs for cache cleaning
When doing cache maintenance for the page tables, we currently use the architecture specific dmac_clean_range() function, which is no longer available. Instead of using architecture specific, functions for cache maintenance, use the generic DMA APIs for cleaning the caches. Change-Id: I086d12da8205c0a5fbc65efc4ec6534b1ee6ab39 Signed-off-by: Isaac J. Manjarres <[email protected]>
This commit is contained in:
parent
311b359886
commit
2a6287c62a
1 changed files with 46 additions and 13 deletions
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/io-pgtable-fast.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
|
||||
#define AV8L_FAST_MAX_ADDR_BITS 48
|
||||
|
|
@ -145,6 +146,46 @@ struct av8l_fast_io_pgtable {
|
|||
|
||||
#define iopte_pmd_offset(pmds, iova) (pmds + (iova >> 12))
|
||||
|
||||
static inline dma_addr_t av8l_dma_addr(void *addr)
|
||||
{
|
||||
if (is_vmalloc_addr(addr))
|
||||
return page_to_phys(vmalloc_to_page(addr)) +
|
||||
offset_in_page(addr);
|
||||
return virt_to_phys(addr);
|
||||
}
|
||||
|
||||
static void __av8l_clean_range(struct device *dev, void *start, void *end)
|
||||
{
|
||||
size_t size;
|
||||
void *region_end;
|
||||
unsigned long page_end;
|
||||
|
||||
if (is_vmalloc_addr(start)) {
|
||||
while (start < end) {
|
||||
page_end = round_down((unsigned long)start + PAGE_SIZE,
|
||||
PAGE_SIZE);
|
||||
region_end = min_t(void *, end, page_end);
|
||||
size = region_end - start;
|
||||
dma_sync_single_for_device(dev, av8l_dma_addr(start),
|
||||
size, DMA_TO_DEVICE);
|
||||
start = region_end;
|
||||
}
|
||||
} else {
|
||||
size = end - start;
|
||||
dma_sync_single_for_device(dev, av8l_dma_addr(start), size,
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
static void av8l_clean_range(struct io_pgtable_ops *ops,
|
||||
av8l_fast_iopte *start, av8l_fast_iopte *end)
|
||||
{
|
||||
struct io_pgtable *iop = iof_pgtable_ops_to_pgtable(ops);
|
||||
|
||||
if (!(iop->cfg.quirks & IO_PGTABLE_QUIRK_NO_DMA))
|
||||
__av8l_clean_range(iop->cfg.iommu_dev, start, end);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
|
@ -182,7 +223,7 @@ void av8l_fast_clear_stale_ptes(struct io_pgtable_ops *ops, bool skip_sync)
|
|||
if (!(*pmdp & AV8L_FAST_PTE_VALID)) {
|
||||
*pmdp = 0;
|
||||
if (!skip_sync)
|
||||
dmac_clean_range(pmdp, pmdp + 1);
|
||||
__av8l_clean_range(pmdp, pmdp + 1);
|
||||
}
|
||||
pmdp++;
|
||||
}
|
||||
|
|
@ -193,15 +234,6 @@ static void __av8l_check_for_stale_tlb(av8l_fast_iopte *ptep)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void av8l_clean_range(struct io_pgtable_ops *ops,
|
||||
av8l_fast_iopte *start, av8l_fast_iopte *end)
|
||||
{
|
||||
struct io_pgtable *iop = iof_pgtable_ops_to_pgtable(ops);
|
||||
|
||||
if (!(iop->cfg.quirks & IO_PGTABLE_QUIRK_NO_DMA))
|
||||
dmac_clean_range(start, end);
|
||||
}
|
||||
|
||||
static av8l_fast_iopte
|
||||
av8l_fast_prot_to_pte(struct av8l_fast_io_pgtable *data, int prot)
|
||||
{
|
||||
|
|
@ -445,7 +477,7 @@ av8l_fast_prepopulate_pgtables(struct av8l_fast_io_pgtable *data,
|
|||
ptep = ((av8l_fast_iopte *)data->pgd) + i;
|
||||
*ptep = pte;
|
||||
}
|
||||
dmac_clean_range(data->pgd, data->pgd + 4);
|
||||
__av8l_clean_range(cfg->iommu_dev, data->pgd, data->pgd + 4);
|
||||
|
||||
/*
|
||||
* We have 4 puds, each of which can point to 512 pmds, so we'll
|
||||
|
|
@ -463,13 +495,14 @@ av8l_fast_prepopulate_pgtables(struct av8l_fast_io_pgtable *data,
|
|||
pages[pg++] = page;
|
||||
|
||||
addr = page_address(page);
|
||||
dmac_clean_range(addr, addr + SZ_4K);
|
||||
__av8l_clean_range(cfg->iommu_dev, addr, addr + SZ_4K);
|
||||
|
||||
pte = page_to_phys(page) | AV8L_FAST_PTE_TYPE_TABLE;
|
||||
pudp = data->puds[i] + j;
|
||||
*pudp = pte;
|
||||
}
|
||||
dmac_clean_range(data->puds[i], data->puds[i] + 512);
|
||||
__av8l_clean_range(cfg->iommu_dev, data->puds[i],
|
||||
data->puds[i] + 512);
|
||||
}
|
||||
|
||||
if (WARN_ON(pg != NUM_PGTBL_PAGES))
|
||||
|
|
|
|||
Loading…
Reference in a new issue