staging: android: ion: set dma ops for platform device

Set dma ops for platform device.

Change-Id: I09c43104774f8b5b95f816293a44d280d8d0f23a
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
This commit is contained in:
Jianqun Xu
2021-03-08 17:48:03 +08:00
committed by Tao Huang
parent 319e24e84a
commit 6a40ead69f
2 changed files with 59 additions and 2 deletions

View File

@@ -294,6 +294,7 @@ size_t ion_heap_freelist_size(struct ion_heap *heap);
* @gfp_mask: gfp_mask to use from alloc
* @order: order of pages in the pool
* @list: plist node for list of pools
* @dev: device for the pool
*
* Allows you to keep a pool of pre allocated pages to use from your heap.
* Keeping a pool of pages that is ready for dma, ie any cached mapping have
@@ -309,6 +310,7 @@ struct ion_page_pool {
gfp_t gfp_mask;
unsigned int order;
struct plist_node list;
struct device *dev;
};
struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order);

View File

@@ -5,7 +5,10 @@
* Copyright (C) 2011 Google, Inc.
*/
#include <linux/dma-buf.h>
#include <linux/list.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/sched/signal.h>
@@ -70,6 +73,20 @@ static struct page *ion_page_pool_remove(struct ion_page_pool *pool, bool high)
return page;
}
static void page_sync_for_device(struct device *dev, struct page *page,
size_t size, enum dma_data_direction dir)
{
struct scatterlist sg;
if (!dev || !page)
return;
sg_init_table(&sg, 1);
sg_set_page(&sg, page, size, 0);
sg_dma_address(&sg) = page_to_phys(page);
dma_sync_sg_for_device(dev, &sg, 1, dir);
}
struct page *ion_page_pool_alloc(struct ion_page_pool *pool)
{
struct page *page = NULL;
@@ -83,8 +100,12 @@ struct page *ion_page_pool_alloc(struct ion_page_pool *pool)
page = ion_page_pool_remove(pool, false);
mutex_unlock(&pool->mutex);
if (!page)
if (!page) {
page = ion_page_pool_alloc_pages(pool);
page_sync_for_device(pool->dev, page,
PAGE_SIZE << pool->order,
DMA_BIDIRECTIONAL);
}
return page;
}
@@ -148,9 +169,33 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
return freed;
}
static const struct platform_device_info ion_dev_info = {
.name = "ion-pool",
.id = PLATFORM_DEVID_AUTO,
.dma_mask = DMA_BIT_MASK(32),
};
static struct platform_device *platform_device_register_dma(const char *name)
{
struct platform_device *pdev;
int ret;
pdev = platform_device_register_full(&ion_dev_info);
if (pdev) {
ret = of_dma_configure(&pdev->dev, NULL, true);
if (ret) {
platform_device_unregister(pdev);
pdev = NULL;
}
}
return pdev;
}
struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order)
{
struct ion_page_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
struct platform_device *pdev;
struct ion_page_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
if (!pool)
return NULL;
@@ -163,10 +208,20 @@ struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order)
mutex_init(&pool->mutex);
plist_node_init(&pool->list, order);
pdev = platform_device_register_dma("ion_pool");
if (!IS_ERR(pdev))
pool->dev = &pdev->dev;
return pool;
}
void ion_page_pool_destroy(struct ion_page_pool *pool)
{
if (pool->dev) {
struct platform_device *pdev = to_platform_device(pool->dev);
of_dma_deconfigure(&pdev->dev);
platform_device_unregister(pdev);
}
kfree(pool);
}