From 850a405cf5dcceab3cde0a2157f425187e53edf5 Mon Sep 17 00:00:00 2001 From: Ivan Priest Date: Thu, 21 Feb 2019 19:07:50 +0000 Subject: [PATCH] [NEUS7920-133]wlbt: report miframman usage in /proc Add /proc/driver/mifctrl/rammanX/used,free This is to track shared DRAM usage. Change-Id: Icafc2ae0a08701428f3d9e92a5993c1145f043c6 SCSC-Bug-Id: SSB-49317 Signed-off-by: Ivan Priest --- drivers/misc/samsung/scsc/mifproc.c | 205 ++++++++++++++++++++++++-- drivers/misc/samsung/scsc/mifproc.h | 3 + drivers/misc/samsung/scsc/miframman.c | 9 +- drivers/misc/samsung/scsc/miframman.h | 11 +- drivers/misc/samsung/scsc/mxman.c | 4 +- 5 files changed, 213 insertions(+), 19 deletions(-) diff --git a/drivers/misc/samsung/scsc/mifproc.c b/drivers/misc/samsung/scsc/mifproc.c index e0d684d00bb5..c46b1f340ae1 100644 --- a/drivers/misc/samsung/scsc/mifproc.c +++ b/drivers/misc/samsung/scsc/mifproc.c @@ -9,8 +9,12 @@ #include #include "mifproc.h" #include "scsc_mif_abs.h" +#include "miframman.h" + +#define MX_MAX_PROC_RAMMAN 2 /* Number of RAMMANs to track */ static struct proc_dir_entry *procfs_dir; +static struct proc_dir_entry *procfs_dir_ramman[MX_MAX_PROC_RAMMAN]; /* WARNING --- SINGLETON FOR THE TIME BEING */ /* EXTEND PROC ENTRIES IF NEEDED!!!!! */ @@ -29,6 +33,14 @@ MIF_PROCFS_RW_FILE_OPS(mif_reg); MIF_PROCFS_SEQ_FILE_OPS(mif_dbg); */ +/* miframman ops */ +MIF_PROCFS_RO_FILE_OPS(ramman_total); +MIF_PROCFS_RO_FILE_OPS(ramman_offset); +MIF_PROCFS_RO_FILE_OPS(ramman_start); +MIF_PROCFS_RO_FILE_OPS(ramman_free); +MIF_PROCFS_RO_FILE_OPS(ramman_used); +MIF_PROCFS_RO_FILE_OPS(ramman_size); + static ssize_t mifprocfs_mif_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { char buf[128]; @@ -262,14 +274,115 @@ static int mifprocfs_mif_dbg_show(struct seq_file *m, void *v) } */ +/* Total space in the memory region containing this ramman (assumes one region per ramman) */ +static ssize_t mifprocfs_ramman_total_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[128]; + int pos = 0; + const size_t bufsz = sizeof(buf); + struct miframman *ramman = (struct miframman *)file->private_data; + + pos += scnprintf(buf + pos, bufsz - pos, "%zd\n", (ptrdiff_t)(ramman->start_dram - ramman->start_region) + ramman->size_pool); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +/* Offset of the pool within the region (the space before is reserved by FW) */ +static ssize_t mifprocfs_ramman_offset_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[128]; + int pos = 0; + const size_t bufsz = sizeof(buf); + struct miframman *ramman = (struct miframman *)file->private_data; + + pos += scnprintf(buf + pos, bufsz - pos, "%zd\n", (ptrdiff_t)(ramman->start_dram - ramman->start_region)); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +/* Start address of the pool within the region */ +static ssize_t mifprocfs_ramman_start_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[128]; + int pos = 0; + const size_t bufsz = sizeof(buf); + struct miframman *ramman = (struct miframman *)file->private_data; + + pos += scnprintf(buf + pos, bufsz - pos, "%p\n", ramman->start_dram); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +/* Size of the pool */ +static ssize_t mifprocfs_ramman_size_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[128]; + int pos = 0; + const size_t bufsz = sizeof(buf); + struct miframman *ramman = (struct miframman *)file->private_data; + + pos += scnprintf(buf + pos, bufsz - pos, "%zd\n", ramman->size_pool); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +/* Space remaining within the pool */ +static ssize_t mifprocfs_ramman_free_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[128]; + int pos = 0; + const size_t bufsz = sizeof(buf); + struct miframman *ramman = (struct miframman *)file->private_data; + + pos += scnprintf(buf + pos, bufsz - pos, "%u\n", ramman->free_mem); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +/* Bytes used within the pool */ +static ssize_t mifprocfs_ramman_used_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[128]; + int pos = 0; + const size_t bufsz = sizeof(buf); + struct miframman *ramman = (struct miframman *)file->private_data; + + pos += scnprintf(buf + pos, bufsz - pos, "%zd\n", ramman->size_pool - (size_t)ramman->free_mem); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + static const char *procdir = "driver/mif_ctrl"; +static int refcount; #define MIF_DIRLEN 128 +static struct proc_dir_entry *create_procfs_dir(void) +{ + char dir[MIF_DIRLEN]; + + if (refcount++ == 0) { + (void)snprintf(dir, sizeof(dir), "%s", procdir); + procfs_dir = proc_mkdir(dir, NULL); + } + return procfs_dir; +} + +static void destroy_procfs_dir(void) +{ + char dir[MIF_DIRLEN]; + + if (--refcount == 0) { + (void)snprintf(dir, sizeof(dir), "%s", procdir); + remove_proc_entry(dir, NULL); + procfs_dir = NULL; + } + WARN_ON(refcount < 0); +} + int mifproc_create_proc_dir(struct scsc_mif_abs *mif) { - char dir[MIF_DIRLEN]; struct proc_dir_entry *parent; /* WARNING --- SINGLETON FOR THE TIME BEING */ @@ -277,14 +390,12 @@ int mifproc_create_proc_dir(struct scsc_mif_abs *mif) if (mif_global) return -EBUSY; - (void)snprintf(dir, sizeof(dir), "%s", procdir); - parent = proc_mkdir(dir, NULL); + /* Ref the root dir */ + parent = create_procfs_dir(); if (parent) { #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)) parent->data = NULL; #endif - procfs_dir = parent; - MIF_PROCFS_ADD_FILE(NULL, mif_writemem, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); MIF_PROCFS_ADD_FILE(NULL, mif_dump, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); MIF_PROCFS_ADD_FILE(NULL, mif_reg, parent, S_IRUSR | S_IRGRP); @@ -308,8 +419,6 @@ err: void mifproc_remove_proc_dir(void) { if (procfs_dir) { - char dir[MIF_DIRLEN]; - MIF_PROCFS_REMOVE_FILE(mif_writemem, procfs_dir); MIF_PROCFS_REMOVE_FILE(mif_dump, procfs_dir); MIF_PROCFS_REMOVE_FILE(mif_reg, procfs_dir); @@ -317,10 +426,86 @@ void mifproc_remove_proc_dir(void) MIF_PROCFS_REMOVE_FILE(mif_dbg, procfs_dir); */ - (void)snprintf(dir, sizeof(dir), "%s", procdir); - remove_proc_entry(dir, NULL); - procfs_dir = NULL; + /* De-ref the root dir */ + destroy_procfs_dir(); } mif_global = NULL; } + +/* /proc/driver/mif_ctrl/rammanX */ +static const char *ramman_procdir = "ramman"; +struct miframman *proc_miframman[MX_MAX_PROC_RAMMAN]; +static int ramman_instance; + +int mifproc_create_ramman_proc_dir(struct miframman *ramman) +{ + char dir[MIF_DIRLEN]; + struct proc_dir_entry *parent; + struct proc_dir_entry *root; + + if ((ramman_instance > ARRAY_SIZE(proc_miframman) - 1)) + return -EINVAL; + + /* Ref the root dir /proc/driver/mif_ctrl */ + root = create_procfs_dir(); + if (!root) + return -EINVAL; + + (void)snprintf(dir, sizeof(dir), "%s%d", ramman_procdir, ramman_instance); + parent = proc_mkdir(dir, root); + if (parent) { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)) + parent->data = NULL; +#endif + MIF_PROCFS_ADD_FILE(ramman, ramman_total, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + MIF_PROCFS_ADD_FILE(ramman, ramman_offset, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + MIF_PROCFS_ADD_FILE(ramman, ramman_start, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + MIF_PROCFS_ADD_FILE(ramman, ramman_size, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + MIF_PROCFS_ADD_FILE(ramman, ramman_free, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + MIF_PROCFS_ADD_FILE(ramman, ramman_used, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + + procfs_dir_ramman[ramman_instance] = parent; + proc_miframman[ramman_instance] = ramman; + + ramman_instance++; + + } else { + SCSC_TAG_INFO(MIF, "failed to create /proc dir\n"); + destroy_procfs_dir(); + return -EINVAL; + } + + return 0; +} + +void mifproc_remove_ramman_proc_dir(struct miframman *ramman) +{ + (void)ramman; + + if (ramman_instance <= 0) { + WARN_ON(ramman_instance < 0); + return; + } + + --ramman_instance; + + if (procfs_dir_ramman[ramman_instance]) { + char dir[MIF_DIRLEN]; + + MIF_PROCFS_REMOVE_FILE(ramman_total, procfs_dir_ramman[ramman_instance]); + MIF_PROCFS_REMOVE_FILE(ramman_offset, procfs_dir_ramman[ramman_instance]); + MIF_PROCFS_REMOVE_FILE(ramman_start, procfs_dir_ramman[ramman_instance]); + MIF_PROCFS_REMOVE_FILE(ramman_size, procfs_dir_ramman[ramman_instance]); + MIF_PROCFS_REMOVE_FILE(ramman_free, procfs_dir_ramman[ramman_instance]); + MIF_PROCFS_REMOVE_FILE(ramman_used, procfs_dir_ramman[ramman_instance]); + + (void)snprintf(dir, sizeof(dir), "%s%d", ramman_procdir, ramman_instance); + remove_proc_entry(dir, procfs_dir); + procfs_dir_ramman[ramman_instance] = NULL; + proc_miframman[ramman_instance] = NULL; + } + + /* De-ref the root dir */ + destroy_procfs_dir(); +} diff --git a/drivers/misc/samsung/scsc/mifproc.h b/drivers/misc/samsung/scsc/mifproc.h index 12325306ffcf..ef1bd166c61c 100644 --- a/drivers/misc/samsung/scsc/mifproc.h +++ b/drivers/misc/samsung/scsc/mifproc.h @@ -103,9 +103,12 @@ #define MIF_PROCFS_REMOVE_FILE(name, parent) remove_proc_entry(# name, parent) struct scsc_mif_abs; +struct miframman; int mifproc_create_proc_dir(struct scsc_mif_abs *mif); void mifproc_remove_proc_dir(void); +int mifproc_create_ramman_proc_dir(struct miframman *miframman); +void mifproc_remove_ramman_proc_dir(struct miframman *miframman); struct mifproc { }; diff --git a/drivers/misc/samsung/scsc/miframman.c b/drivers/misc/samsung/scsc/miframman.c index 3663b657d609..0dd6daade843 100644 --- a/drivers/misc/samsung/scsc/miframman.c +++ b/drivers/misc/samsung/scsc/miframman.c @@ -12,10 +12,10 @@ #include "scsc/api/bt_audio.h" #include "miframman.h" - +#include "mifproc.h" /* Caller should provide locking */ -void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool) +void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool, void *start_region) { mutex_init(&ram->lock); @@ -34,9 +34,12 @@ void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool) memset(ram->bitmap, BLOCK_FREE, sizeof(ram->bitmap)); + ram->start_region = start_region; /* For monitoring purposes only */ ram->start_dram = start_dram; ram->size_pool = size_pool; ram->free_mem = ram->num_blocks * MIFRAMMAN_BLOCK_SIZE; + + mifproc_create_ramman_proc_dir(ram); } void miframabox_init(struct mifabox *mifabox, void *start_aboxram) @@ -183,6 +186,8 @@ void miframman_deinit(struct miframman *ram) ram->start_dram = NULL; ram->size_pool = 0; ram->free_mem = 0; + + mifproc_remove_ramman_proc_dir(ram); } void miframabox_deinit(struct mifabox *mifabox) diff --git a/drivers/misc/samsung/scsc/miframman.h b/drivers/misc/samsung/scsc/miframman.h index 0c08c0adcd09..d7fb1142d132 100644 --- a/drivers/misc/samsung/scsc/miframman.h +++ b/drivers/misc/samsung/scsc/miframman.h @@ -16,7 +16,7 @@ struct miframman; struct mifabox; -void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool); +void miframman_init(struct miframman *ram, void *start_dram, size_t size_pool, void *start_region); void miframabox_init(struct mifabox *mifabox, void *start_aboxram); void *miframman_alloc(struct miframman *ram, size_t nbytes, size_t align); void miframman_free(struct miframman *ram, void *mem); @@ -34,11 +34,12 @@ void miframabox_deinit(struct mifabox *mifabox); /* Inclusion in core.c treat it as opaque */ struct miframman { - void *start_dram; - size_t size_pool; + void *start_region; /* Base address of region containing the pool */ + void *start_dram; /* Base address of allocator pool */ + size_t size_pool; /* Size of allocator pool */ char bitmap[MIFRAMMAN_NUM_BLOCKS]; /* Zero initialized-> all blocks free */ - u32 num_blocks; - u32 free_mem; + u32 num_blocks; /* Blocks of MIFRAMMAN_BLOCK_SIZE in pool */ + u32 free_mem; /* Bytes remaining in allocator pool */ struct mutex lock; }; diff --git a/drivers/misc/samsung/scsc/mxman.c b/drivers/misc/samsung/scsc/mxman.c index fc9cbd91ff29..b38178e4fa9a 100755 --- a/drivers/misc/samsung/scsc/mxman.c +++ b/drivers/misc/samsung/scsc/mxman.c @@ -1068,8 +1068,8 @@ static int mxman_start(struct mxman *mxman) length_mifram_heap2 = MX_DRAM_SIZE_SECTION_2 - ((sizeof(struct scsc_bt_audio_abox) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); - miframman_init(scsc_mx_get_ramman(mxman->mx), start_mifram_heap, length_mifram_heap); - miframman_init(scsc_mx_get_ramman2(mxman->mx), start_mifram_heap2, length_mifram_heap2); + miframman_init(scsc_mx_get_ramman(mxman->mx), start_mifram_heap, length_mifram_heap, start_dram); + miframman_init(scsc_mx_get_ramman2(mxman->mx), start_mifram_heap2, length_mifram_heap2, start_mifram_heap2); miframabox_init(scsc_mx_get_aboxram(mxman->mx), start_mifram_heap2 + length_mifram_heap2); mifmboxman_init(scsc_mx_get_mboxman(mxman->mx)); mifintrbit_init(scsc_mx_get_intrbit(mxman->mx), mif); -- 2.20.1