diff --git a/drivers/dma-buf/rk_heaps/rk-cma-heap.c b/drivers/dma-buf/rk_heaps/rk-cma-heap.c index 8b9a78006413..5c6aa681407a 100644 --- a/drivers/dma-buf/rk_heaps/rk-cma-heap.c +++ b/drivers/dma-buf/rk_heaps/rk-cma-heap.c @@ -25,7 +25,8 @@ #include #include #include - +#include +#include "../../../mm/cma.h" #include "rk-dma-heap.h" struct rk_cma_heap { @@ -572,6 +573,8 @@ static const struct rk_dma_heap_ops rk_cma_heap_ops = { .free_contig_pages = rk_cma_heap_free_pages, }; +static int cma_procfs_show(struct seq_file *s, void *private); + static int __rk_add_cma_heap(struct cma *cma, void *data) { struct rk_cma_heap *cma_heap; @@ -595,6 +598,10 @@ static int __rk_add_cma_heap(struct cma *cma, void *data) return ret; } + if (cma_heap->heap->procfs) + proc_create_single_data("alloc_bitmap", 0, cma_heap->heap->procfs, + cma_procfs_show, cma); + return 0; } @@ -608,5 +615,62 @@ static int rk_add_default_cma_heap(void) return __rk_add_cma_heap(cma, NULL); } module_init(rk_add_default_cma_heap); + +static void cma_procfs_format_array(char *buf, size_t bufsize, u32 *array, int array_size) +{ + int i = 0; + + while (--array_size >= 0) { + size_t len; + char term = (array_size && (++i % 8)) ? ' ' : '\n'; + + len = snprintf(buf, bufsize, "%08X%c", *array++, term); + buf += len; + bufsize -= len; + } +} + +static void cma_procfs_show_bitmap(struct seq_file *s, struct cma *cma) +{ + int elements = DIV_ROUND_UP(cma_bitmap_maxno(cma), BITS_PER_BYTE * sizeof(u32)); + int size = elements * 9; + u32 *array = (u32 *)cma->bitmap; + char *buf; + + buf = kmalloc(size + 1, GFP_KERNEL); + if (!buf) + return; + + buf[size] = 0; + + cma_procfs_format_array(buf, size + 1, array, elements); + seq_printf(s, "%s", buf); + kfree(buf); +} + +static u64 cma_procfs_used_get(struct cma *cma) +{ + unsigned long used; + + mutex_lock(&cma->lock); + used = bitmap_weight(cma->bitmap, (int)cma_bitmap_maxno(cma)); + mutex_unlock(&cma->lock); + + return (u64)used << cma->order_per_bit; +} + +static int cma_procfs_show(struct seq_file *s, void *private) +{ + struct cma *cma = s->private; + u64 used = cma_procfs_used_get(cma); + + seq_printf(s, "Total: %lu KiB\n", cma->count << (PAGE_SHIFT - 10)); + seq_printf(s, " Used: %llu KiB\n\n", used << (PAGE_SHIFT - 10)); + + cma_procfs_show_bitmap(s, cma); + + return 0; +} + MODULE_DESCRIPTION("RockChip DMA-BUF CMA Heap"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma-buf/rk_heaps/rk-dma-heap.c b/drivers/dma-buf/rk_heaps/rk-dma-heap.c index b2687c2d81fd..311d2ec93879 100644 --- a/drivers/dma-buf/rk_heaps/rk-dma-heap.c +++ b/drivers/dma-buf/rk_heaps/rk-dma-heap.c @@ -456,6 +456,8 @@ struct rk_dma_heap *rk_dma_heap_add(const struct rk_dma_heap_export_info *exp_in goto err2; } + heap->procfs = proc_rk_dma_heap_dir; + /* Make sure it doesn't disappear on us */ heap->heap_dev = get_device(heap->heap_dev); diff --git a/drivers/dma-buf/rk_heaps/rk-dma-heap.h b/drivers/dma-buf/rk_heaps/rk-dma-heap.h index 609624f6fa67..3bc750b02023 100644 --- a/drivers/dma-buf/rk_heaps/rk-dma-heap.h +++ b/drivers/dma-buf/rk_heaps/rk-dma-heap.h @@ -93,6 +93,7 @@ struct rk_dma_heap { struct device *heap_dev; bool support_cma; struct seq_file *s; + struct proc_dir_entry *procfs; unsigned long total_size; };