diff options
author | Fernando Guzman Lugo <x0095840@ti.com> | 2010-10-05 15:35:36 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-05 15:30:57 -0700 |
commit | 4dd1944ab7242d76534c97d5fef0ce541a2f1040 (patch) | |
tree | 33d37002e39bc57be95976fcc576bf52139e6c21 /drivers/staging/tidspbridge/core | |
parent | staging: tidspbridge - move shared memory iommu maps to tiomap3430.c (diff) | |
download | linux-dev-4dd1944ab7242d76534c97d5fef0ce541a2f1040.tar.xz linux-dev-4dd1944ab7242d76534c97d5fef0ce541a2f1040.zip |
staging: tidspbridge - rename bridge_brd_mem_map/unmap to a proper name
Now these functions only map user space addresses to dsp virtual
addresses, so now the functions have a more meaningful name.
Also now user_to_dsp_map returns the mapped address.
Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/tidspbridge/core')
-rw-r--r-- | drivers/staging/tidspbridge/core/_tiomap.h | 24 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/core/tiomap3430.c | 153 |
2 files changed, 98 insertions, 79 deletions
diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index c1bf95d756b3..877749258acb 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -383,4 +383,28 @@ extern s32 dsp_debug; */ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgs struct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + #endif /* _TIOMAP_ */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 3749cd580307..0e5b8051bf20 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -97,12 +97,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes, u32 mem_type); -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages); -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, - u32 da); static int bridge_dev_create(struct bridge_dev_context **dev_cntxt, struct dev_object *hdev_obj, @@ -110,9 +104,6 @@ static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, - struct page **usr_pgs); -static u32 user_va2_pa(struct mm_struct *mm, u32 address); static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, u32 va, u32 size, struct hw_mmu_map_attrs_t *map_attrs); @@ -182,8 +173,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_brd_set_state, bridge_brd_mem_copy, bridge_brd_mem_write, - bridge_brd_mem_map, - bridge_brd_mem_un_map, /* The following CHNL functions are provided by chnl_io.lib: */ bridge_chnl_create, bridge_chnl_destroy, @@ -1154,22 +1143,77 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, } /* - * ======== bridge_brd_mem_map ======== - * This function maps MPU buffer to the DSP address space. It performs - * linear to physical address translation if required. It translates each - * page since linear addresses can be physically non-contiguous - * All address & size arguments are assumed to be page aligned (in proc.c) + * ======== user_va2_pa ======== + * Purpose: + * This function walks through the page tables to convert a userland + * virtual address to physical address + */ +static u32 user_va2_pa(struct mm_struct *mm, u32 address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset(mm, address); + if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { + pmd = pmd_offset(pgd, address); + if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { + ptep = pte_offset_map(pmd, address); + if (ptep) { + pte = *ptep; + if (pte_present(pte)) + return pte & PAGE_MASK; + } + } + } + + return 0; +} + +/** + * get_io_pages() - pin and get pages of io user's buffer. + * @mm: mm_struct Pointer of the process. + * @uva: Virtual user space address. + * @pages Pages to be pined. + * @usr_pgs struct page array pointer where the user pages will be stored * - * TODO: Disable MMU while updating the page tables (but that'll stall DSP) */ -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx, - u32 uva, u32 da, u32 size, u32 attr, - struct page **usr_pgs) +static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, + struct page **usr_pgs) +{ + u32 pa; + int i; + struct page *pg; + + for (i = 0; i < pages; i++) { + pa = user_va2_pa(mm, uva); + if (!pfn_valid(__phys_to_pfn(pa))) + break; + + pg = PHYS_TO_PAGE(pa); + usr_pgs[i] = pg; + get_page(pg); + } + return i; +} + +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgs struct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs) { int res, w; unsigned pages, i; - struct iommu *mmu = dev_ctx->dsp_mmu; struct vm_area_struct *vma; struct mm_struct *mm = current->mm; struct sg_table *sgt; @@ -1226,7 +1270,7 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx, da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); if (!IS_ERR_VALUE(da)) - return 0; + return da; res = (int)da; sg_free_table(sgt); @@ -1239,21 +1283,21 @@ err_pages: return res; } -/* - * ======== bridge_brd_mem_un_map ======== - * Invalidate the PTEs for the DSP VA block to be unmapped. +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. * - * PTEs of a mapped memory block are contiguous in any page table - * So, instead of looking up the PTE address for every 4K block, - * we clear consecutive PTEs until we unmap all the bytes */ -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da) +int user_to_dsp_unmap(struct iommu *mmu, u32 da) { unsigned i; struct sg_table *sgt; struct scatterlist *sg; - sgt = iommu_vunmap(dev_ctx->dsp_mmu, da); + sgt = iommu_vunmap(mmu, da); if (!sgt) return -EFAULT; @@ -1265,55 +1309,6 @@ static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da) return 0; } - -static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, - struct page **usr_pgs) -{ - u32 pa; - int i; - struct page *pg; - - for (i = 0; i < pages; i++) { - pa = user_va2_pa(mm, uva); - - if (!pfn_valid(__phys_to_pfn(pa))) - break; - - pg = PHYS_TO_PAGE(pa); - usr_pgs[i] = pg; - get_page(pg); - } - return i; -} - -/* - * ======== user_va2_pa ======== - * Purpose: - * This function walks through the page tables to convert a userland - * virtual address to physical address - */ -static u32 user_va2_pa(struct mm_struct *mm, u32 address) -{ - pgd_t *pgd; - pmd_t *pmd; - pte_t *ptep, pte; - - pgd = pgd_offset(mm, address); - if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { - pmd = pmd_offset(pgd, address); - if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { - ptep = pte_offset_map(pmd, address); - if (ptep) { - pte = *ptep; - if (pte_present(pte)) - return pte & PAGE_MASK; - } - } - } - - return 0; -} - /* * ======== pte_update ======== * This function calculates the optimum page-aligned addresses and sizes |