1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * CMA ProcFS Interface
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2022 Rockchip Electronics Co. Ltd.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/cma.h>
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/proc_fs.h>
11*4882a593Smuzhiyun #include <linux/seq_file.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include "../../../mm/cma.h"
15*4882a593Smuzhiyun
cma_procfs_format_array(char * buf,size_t bufsize,u32 * array,int array_size)16*4882a593Smuzhiyun static void cma_procfs_format_array(char *buf, size_t bufsize, u32 *array, int array_size)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun int i = 0;
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun while (--array_size >= 0) {
21*4882a593Smuzhiyun size_t len;
22*4882a593Smuzhiyun char term = (array_size && (++i % 8)) ? ' ' : '\n';
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun len = snprintf(buf, bufsize, "%08X%c", *array++, term);
25*4882a593Smuzhiyun buf += len;
26*4882a593Smuzhiyun bufsize -= len;
27*4882a593Smuzhiyun }
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun
cma_procfs_show_bitmap(struct seq_file * s,struct cma * cma)30*4882a593Smuzhiyun static void cma_procfs_show_bitmap(struct seq_file *s, struct cma *cma)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun int elements = DIV_ROUND_UP(cma_bitmap_maxno(cma), BITS_PER_BYTE * sizeof(u32));
33*4882a593Smuzhiyun int size = elements * 9;
34*4882a593Smuzhiyun u32 *array = (u32 *)cma->bitmap;
35*4882a593Smuzhiyun char *buf;
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun buf = kmalloc(size + 1, GFP_KERNEL);
38*4882a593Smuzhiyun if (!buf)
39*4882a593Smuzhiyun return;
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun buf[size] = 0;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun cma_procfs_format_array(buf, size + 1, array, elements);
44*4882a593Smuzhiyun seq_printf(s, "%s", buf);
45*4882a593Smuzhiyun kfree(buf);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
cma_procfs_used_get(struct cma * cma)48*4882a593Smuzhiyun static u64 cma_procfs_used_get(struct cma *cma)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun unsigned long used;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun mutex_lock(&cma->lock);
53*4882a593Smuzhiyun used = bitmap_weight(cma->bitmap, (int)cma_bitmap_maxno(cma));
54*4882a593Smuzhiyun mutex_unlock(&cma->lock);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun return (u64)used << cma->order_per_bit;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun
cma_procfs_show(struct seq_file * s,void * private)59*4882a593Smuzhiyun static int cma_procfs_show(struct seq_file *s, void *private)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun struct cma *cma = s->private;
62*4882a593Smuzhiyun u64 used = cma_procfs_used_get(cma);
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun seq_printf(s, "Total: %lu KiB\n", cma->count << (PAGE_SHIFT - 10));
65*4882a593Smuzhiyun seq_printf(s, " Used: %llu KiB\n\n", used << (PAGE_SHIFT - 10));
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun cma_procfs_show_bitmap(s, cma);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun return 0;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
cma_procfs_add_one(struct cma * cma,void * data)72*4882a593Smuzhiyun static int cma_procfs_add_one(struct cma *cma, void *data)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun struct proc_dir_entry *root = data;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun proc_create_single_data(cma->name, 0, root, cma_procfs_show, cma);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun return 0;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
rk_cma_procfs_init(void)81*4882a593Smuzhiyun static int rk_cma_procfs_init(void)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun struct proc_dir_entry *root = proc_mkdir("rk_cma", NULL);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun return cma_for_each_area(cma_procfs_add_one, (void *)root);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun late_initcall_sync(rk_cma_procfs_init);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun MODULE_LICENSE("GPL");
90*4882a593Smuzhiyun MODULE_AUTHOR("Jianqun Xu <jay.xu@rock-chips.com>");
91*4882a593Smuzhiyun MODULE_DESCRIPTION("ROCKCHIP CMA PROCFS Driver");
92*4882a593Smuzhiyun MODULE_ALIAS("platform:rk-cma");
93