|
@@ -355,20 +355,15 @@ EXPORT_SYMBOL(dma_pool_alloc);
|
|
|
|
|
|
static struct dma_page *pool_find_page(struct dma_pool *pool, dma_addr_t dma)
|
|
|
{
|
|
|
- unsigned long flags;
|
|
|
struct dma_page *page;
|
|
|
|
|
|
- spin_lock_irqsave(&pool->lock, flags);
|
|
|
list_for_each_entry(page, &pool->page_list, page_list) {
|
|
|
if (dma < page->dma)
|
|
|
continue;
|
|
|
if (dma < (page->dma + pool->allocation))
|
|
|
- goto done;
|
|
|
+ return page;
|
|
|
}
|
|
|
- page = NULL;
|
|
|
- done:
|
|
|
- spin_unlock_irqrestore(&pool->lock, flags);
|
|
|
- return page;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -386,8 +381,10 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
|
|
|
unsigned long flags;
|
|
|
unsigned int offset;
|
|
|
|
|
|
+ spin_lock_irqsave(&pool->lock, flags);
|
|
|
page = pool_find_page(pool, dma);
|
|
|
if (!page) {
|
|
|
+ spin_unlock_irqrestore(&pool->lock, flags);
|
|
|
if (pool->dev)
|
|
|
dev_err(pool->dev,
|
|
|
"dma_pool_free %s, %p/%lx (bad dma)\n",
|
|
@@ -401,6 +398,7 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
|
|
|
offset = vaddr - page->vaddr;
|
|
|
#ifdef DMAPOOL_DEBUG
|
|
|
if ((dma - page->dma) != offset) {
|
|
|
+ spin_unlock_irqrestore(&pool->lock, flags);
|
|
|
if (pool->dev)
|
|
|
dev_err(pool->dev,
|
|
|
"dma_pool_free %s, %p (bad vaddr)/%Lx\n",
|
|
@@ -418,6 +416,7 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
|
|
|
chain = *(int *)(page->vaddr + chain);
|
|
|
continue;
|
|
|
}
|
|
|
+ spin_unlock_irqrestore(&pool->lock, flags);
|
|
|
if (pool->dev)
|
|
|
dev_err(pool->dev, "dma_pool_free %s, dma %Lx "
|
|
|
"already free\n", pool->name,
|
|
@@ -432,7 +431,6 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
|
|
|
memset(vaddr, POOL_POISON_FREED, pool->size);
|
|
|
#endif
|
|
|
|
|
|
- spin_lock_irqsave(&pool->lock, flags);
|
|
|
page->in_use--;
|
|
|
*(int *)vaddr = page->offset;
|
|
|
page->offset = offset;
|