mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user