blackfin: use bitmap library functions

The bitmap library provides more efficient functions than accessing
individual bits with bitops.

This uses bitmap_find_next_zero_area() to find a continuing zero area,
and uses bitmap_set()/bitmap_clear() to set/clear specified bit area.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: uclinux-dist-devel@blackfin.uclinux.org
Signed-off-by: Bob Liu <lliubbo@gmail.com>
This commit is contained in:
Akinobu Mita 2012-11-25 16:48:23 +09:00 committed by Bob Liu
parent c428f8eb2f
commit c73bc7026d
1 changed files with 7 additions and 16 deletions

View File

@ -13,6 +13,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/bitmap.h>
static spinlock_t dma_page_lock; static spinlock_t dma_page_lock;
static unsigned long *dma_page; static unsigned long *dma_page;
@ -46,24 +47,17 @@ static inline unsigned int get_pages(size_t size)
static unsigned long __alloc_dma_pages(unsigned int pages) static unsigned long __alloc_dma_pages(unsigned int pages)
{ {
unsigned long ret = 0, flags; unsigned long ret = 0, flags;
int i, count = 0; unsigned long start;
if (dma_initialized == 0) if (dma_initialized == 0)
dma_alloc_init(_ramend - DMA_UNCACHED_REGION, _ramend); dma_alloc_init(_ramend - DMA_UNCACHED_REGION, _ramend);
spin_lock_irqsave(&dma_page_lock, flags); spin_lock_irqsave(&dma_page_lock, flags);
for (i = 0; i < dma_pages;) { start = bitmap_find_next_zero_area(dma_page, dma_pages, 0, pages, 0);
if (test_bit(i++, dma_page) == 0) { if (start < dma_pages) {
if (++count == pages) { ret = dma_base + (start << PAGE_SHIFT);
while (count--) bitmap_set(dma_page, start, pages);
__set_bit(--i, dma_page);
ret = dma_base + (i << PAGE_SHIFT);
break;
}
} else
count = 0;
} }
spin_unlock_irqrestore(&dma_page_lock, flags); spin_unlock_irqrestore(&dma_page_lock, flags);
return ret; return ret;
@ -73,7 +67,6 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages)
{ {
unsigned long page = (addr - dma_base) >> PAGE_SHIFT; unsigned long page = (addr - dma_base) >> PAGE_SHIFT;
unsigned long flags; unsigned long flags;
int i;
if ((page + pages) > dma_pages) { if ((page + pages) > dma_pages) {
printk(KERN_ERR "%s: freeing outside range.\n", __func__); printk(KERN_ERR "%s: freeing outside range.\n", __func__);
@ -81,9 +74,7 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages)
} }
spin_lock_irqsave(&dma_page_lock, flags); spin_lock_irqsave(&dma_page_lock, flags);
for (i = page; i < page + pages; i++) bitmap_clear(dma_page, page, pages);
__clear_bit(i, dma_page);
spin_unlock_irqrestore(&dma_page_lock, flags); spin_unlock_irqrestore(&dma_page_lock, flags);
} }