Loading drivers/platform/msm/msm_bus/msm_bus_arb_adhoc.c +131 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ #include <linux/msm-bus.h> #include "msm_bus_core.h" #include "msm_bus_adhoc.h" #include <trace/events/trace_msm_bus.h> #define NUM_CL_HANDLES 50 #define NUM_LNODES 3 #define MAX_STR_CL 50 struct bus_search_type { struct list_head link; Loading Loading @@ -951,6 +953,7 @@ static int update_request_adhoc(uint32_t cl, unsigned int index) MSM_BUS_DBG("%s: cl: %u index: %d curr: %d num_paths: %d\n", __func__, cl, index, client->curr, client->pdata->usecase->num_paths); msm_bus_dbg_client_data(client->pdata, index , cl); for (i = 0; i < pdata->usecase->num_paths; i++) { src = client->pdata->usecase[index].vectors[i].src; dest = client->pdata->usecase[index].vectors[i].dst; Loading Loading @@ -980,12 +983,135 @@ static int update_request_adhoc(uint32_t cl, unsigned int index) if (log_transaction) getpath_debug(src, lnode, pdata->active_only); } msm_bus_dbg_client_data(client->pdata, index , cl); trace_bus_update_request_end(pdata->name); exit_update_request: mutex_unlock(&msm_bus_adhoc_lock); return ret; } static void free_cl_mem(struct msm_bus_client_handle *cl) { if (cl) { kfree(cl->name); kfree(cl); cl = NULL; } } static int update_bw_adhoc(struct msm_bus_client_handle *cl, u64 ab, u64 ib) { int ret = 0; char *test_cl = "test-client"; bool log_transaction = false; mutex_lock(&msm_bus_adhoc_lock); if (!cl) { MSM_BUS_ERR("%s: Invalid client handle %p", __func__, cl); ret = -ENXIO; goto exit_update_request; } if (!strcmp(test_cl, cl->name)) log_transaction = true; msm_bus_dbg_rec_transaction(cl, ab, ib); if ((cl->cur_ib == ib) && (cl->cur_ab == ab)) { MSM_BUS_DBG("%s:no change in request", cl->name); goto exit_update_request; } ret = update_path(cl->mas, cl->slv, ib, ab, cl->cur_ib, cl->cur_ab, cl->first_hop, cl->active_only); if (ret) { MSM_BUS_ERR("%s: Update path failed! %d active_only %d\n", __func__, ret, cl->active_only); goto exit_update_request; } cl->cur_ib = ib; cl->cur_ab = ab; if (log_transaction) getpath_debug(cl->mas, cl->first_hop, cl->active_only); trace_bus_update_request_end(cl->name); exit_update_request: mutex_unlock(&msm_bus_adhoc_lock); return ret; } static void unregister_adhoc(struct msm_bus_client_handle *cl) { mutex_lock(&msm_bus_adhoc_lock); if (!cl) { MSM_BUS_ERR("%s: Null cl handle passed unregister\n", __func__); goto exit_unregister_client; } MSM_BUS_DBG("%s: Unregistering client %p", __func__, cl); remove_path(cl->mas, cl->slv, cl->cur_ib, cl->cur_ab, cl->first_hop, cl->active_only); msm_bus_dbg_remove_client(cl); kfree(cl); exit_unregister_client: mutex_unlock(&msm_bus_adhoc_lock); return; } static struct msm_bus_client_handle* register_adhoc(uint32_t mas, uint32_t slv, char *name, bool active_only) { struct msm_bus_client_handle *client = NULL; int len = 0; mutex_lock(&msm_bus_adhoc_lock); if (!(mas && slv && name)) { pr_err("%s: Error: src dst name num_paths are required", __func__); goto exit_register; } client = kzalloc(sizeof(struct msm_bus_client_handle), GFP_KERNEL); if (!client) { MSM_BUS_ERR("%s: Error allocating client data", __func__); goto exit_register; } len = strnlen(name, MAX_STR_CL); client->name = kzalloc(len, GFP_KERNEL); if (!client->name) { MSM_BUS_ERR("%s: Error allocating client name buf", __func__); free_cl_mem(client); goto exit_register; } strlcpy(client->name, name, MAX_STR_CL); client->active_only = active_only; client->mas = mas; client->slv = slv; client->first_hop = getpath(client->mas, client->slv); if (client->first_hop < 0) { MSM_BUS_ERR("%s:Failed to find path.src %d dest %d", __func__, client->mas, client->slv); free_cl_mem(client); goto exit_register; } MSM_BUS_DBG("%s:Client handle %p %s", __func__, client, client->name); msm_bus_dbg_add_client(client); exit_register: mutex_unlock(&msm_bus_adhoc_lock); return client; } /** * msm_bus_arb_setops_adhoc() : Setup the bus arbitration ops * @ arb_ops: pointer to the arb ops. Loading @@ -995,4 +1121,8 @@ void msm_bus_arb_setops_adhoc(struct msm_bus_arb_ops *arb_ops) arb_ops->register_client = register_client_adhoc; arb_ops->update_request = update_request_adhoc; arb_ops->unregister_client = unregister_client_adhoc; arb_ops->register_cl = register_adhoc; arb_ops->unregister = unregister_adhoc; arb_ops->update_bw = update_bw_adhoc; } drivers/platform/msm/msm_bus/msm_bus_client_api.c +59 −0 Original line number Diff line number Diff line Loading @@ -81,3 +81,62 @@ void msm_bus_scale_unregister_client(uint32_t cl) } } EXPORT_SYMBOL(msm_bus_scale_unregister_client); /** * msm_bus_scale_register() - Register the clients with the msm bus * driver * @pdata: Platform data of the client, containing src, dest, ab, ib. * Return non-zero value in case of success, 0 in case of failure. * * Client data contains the vectors specifying arbitrated bandwidth (ab) * and instantaneous bandwidth (ib) requested between a particular * src and dest. */ struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, bool active_only) { if (arb_ops.register_cl) return arb_ops.register_cl(mas, slv, name, active_only); else { pr_err("%s: Bus driver not ready.", __func__); return ERR_PTR(-EPROBE_DEFER); } } EXPORT_SYMBOL(msm_bus_scale_register); /** * msm_bus_scale_client_update_bw() - Update the request for bandwidth * from a particular client * * cl: Handle to the client * index: Index into the vector, to which the bw and clock values need to be * updated */ int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) { if (arb_ops.update_request) return arb_ops.update_bw(cl, ab, ib); else { pr_err("%s: Bus driver not ready.", __func__); return -EPROBE_DEFER; } } EXPORT_SYMBOL(msm_bus_scale_update_bw); /** * msm_bus_scale_unregister() - Update the request for bandwidth * from a particular client * * cl: Handle to the client */ void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) { if (arb_ops.unregister) arb_ops.unregister(cl); else pr_err("%s: Bus driver not ready.", __func__); } EXPORT_SYMBOL(msm_bus_scale_unregister); drivers/platform/msm/msm_bus/msm_bus_core.h +27 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,11 @@ struct msm_bus_arb_ops { uint32_t (*register_client)(struct msm_bus_scale_pdata *pdata); int (*update_request)(uint32_t cl, unsigned int index); void (*unregister_client)(uint32_t cl); struct msm_bus_client_handle* (*register_cl)(uint32_t mas, uint32_t slv, char *name, bool active_only); int (*update_bw)(struct msm_bus_client_handle *cl, u64 ab, u64 ib); void (*unregister)(struct msm_bus_client_handle *cl); }; enum { Loading Loading @@ -313,6 +318,11 @@ void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index, uint32_t cl); void msm_bus_dbg_commit_data(const char *fabname, void *cdata, int nmasters, int nslaves, int ntslaves, int op); int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata); int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata, u64 ab, u64 ib); void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata); #else static inline void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index, uint32_t cl) Loading @@ -323,6 +333,23 @@ static inline void msm_bus_dbg_commit_data(const char *fabname, int op) { } static inline void void msm_bus_dbg_remove_client (const struct msm_bus_client_handle *pdata) { } static inline int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata, u64 ab, u64 ib) { return 0; } static inline int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata) { return 0; } #endif #ifdef CONFIG_CORESIGHT Loading drivers/platform/msm/msm_bus/msm_bus_dbg.c +94 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ struct msm_bus_dbg_state { struct msm_bus_cldata { const struct msm_bus_scale_pdata *pdata; const struct msm_bus_client_handle *handle; int index; uint32_t clid; int size; Loading Loading @@ -285,14 +286,17 @@ static ssize_t client_data_read(struct file *file, char __user *buf, int bsize = 0; uint32_t cl = (uint32_t)(uintptr_t)file->private_data; struct msm_bus_cldata *cldata = NULL; const struct msm_bus_client_handle *handle = file->private_data; int found = 0; list_for_each_entry(cldata, &cl_list, list) { if (cldata->clid == cl) { if ((cldata->clid == cl) || (cldata->handle && (cldata->handle == handle))) { found = 1; break; } } if (!found) return 0; Loading Loading @@ -323,6 +327,93 @@ struct dentry *msm_bus_dbg_create(const char *name, mode_t mode, &client_data_fops); } int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata) { struct msm_bus_cldata *cldata; cldata = kzalloc(sizeof(struct msm_bus_cldata), GFP_KERNEL); if (!cldata) { MSM_BUS_DBG("Failed to allocate memory for client data\n"); return -ENOMEM; } cldata->handle = pdata; list_add_tail(&cldata->list, &cl_list); return 0; } int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata, u64 ab, u64 ib) { struct msm_bus_cldata *cldata; int i; struct timespec ts; bool found = false; char *buf = NULL; list_for_each_entry(cldata, &cl_list, list) { if (cldata->handle == pdata) { found = true; break; } } if (!found) return -ENOENT; if (cldata->file == NULL) { if (pdata->name == NULL) { MSM_BUS_DBG("Client doesn't have a name\n"); return -EINVAL; } pr_err("\n%s setting up debugfs %s", __func__, pdata->name); cldata->file = debugfs_create_file(pdata->name, S_IRUGO, clients, (void *)pdata, &client_data_fops); } if (cldata->size < (MAX_BUFF_SIZE - FILL_LIMIT)) i = cldata->size; else { i = 0; cldata->size = 0; } buf = cldata->buffer; ts = ktime_to_timespec(ktime_get()); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n%d.%d\n", (int)ts.tv_sec, (int)ts.tv_nsec); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "master: "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ", pdata->mas); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nslave : "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ", pdata->slv); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nab : "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", ab); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nib : "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", ib); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n"); cldata->size = i; trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec, pdata->name, pdata->mas, pdata->slv, ab, ib); return i; } void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata) { struct msm_bus_cldata *cldata = NULL; list_for_each_entry(cldata, &cl_list, list) { if (cldata->handle == pdata) { debugfs_remove(cldata->file); list_del(&cldata->list); kfree(cldata); break; } } } static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata, int index, uint32_t clid, struct dentry *file) { Loading Loading @@ -416,12 +507,13 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata, for (j = 0; j < pdata->usecase->num_paths; j++) trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec, pdata->name, index, pdata->name, pdata->usecase[index].vectors[j].src, pdata->usecase[index].vectors[j].dst, pdata->usecase[index].vectors[j].ab, pdata->usecase[index].vectors[j].ib); cldata->index = index; cldata->size = i; return i; } Loading include/linux/msm-bus.h +35 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,16 @@ struct msm_bus_scale_pdata { unsigned int active_only; }; struct msm_bus_client_handle { char *name; int mas; int slv; int first_hop; u64 cur_ib; u64 cur_ab; bool active_only; }; /* Scaling APIs */ /* Loading @@ -79,12 +89,19 @@ int __init msm_bus_fabric_init_driver(void); uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata); int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index); void msm_bus_scale_unregister_client(uint32_t cl); struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, bool active_only); void msm_bus_scale_unregister(struct msm_bus_client_handle *cl); int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); /* AXI Port configuration APIs */ int msm_bus_axi_porthalt(int master_port); int msm_bus_axi_portunhalt(int master_port); #else static inline int __init msm_bus_fabric_init_driver(void) { return 0; } static struct msm_bus_client_handle dummy_cl; static inline uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata) Loading Loading @@ -112,6 +129,24 @@ static inline int msm_bus_axi_portunhalt(int master_port) { return 0; } static inline struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, bool active_only) { return &dummy_cl; } static inline void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) { } static inline int msm_bus_scale_update_bw(uint32_t cl, u64 ab, u64 ib) { return 0; } #endif #if defined(CONFIG_OF) && defined(CONFIG_MSM_BUS_SCALING) Loading Loading
drivers/platform/msm/msm_bus/msm_bus_arb_adhoc.c +131 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ #include <linux/msm-bus.h> #include "msm_bus_core.h" #include "msm_bus_adhoc.h" #include <trace/events/trace_msm_bus.h> #define NUM_CL_HANDLES 50 #define NUM_LNODES 3 #define MAX_STR_CL 50 struct bus_search_type { struct list_head link; Loading Loading @@ -951,6 +953,7 @@ static int update_request_adhoc(uint32_t cl, unsigned int index) MSM_BUS_DBG("%s: cl: %u index: %d curr: %d num_paths: %d\n", __func__, cl, index, client->curr, client->pdata->usecase->num_paths); msm_bus_dbg_client_data(client->pdata, index , cl); for (i = 0; i < pdata->usecase->num_paths; i++) { src = client->pdata->usecase[index].vectors[i].src; dest = client->pdata->usecase[index].vectors[i].dst; Loading Loading @@ -980,12 +983,135 @@ static int update_request_adhoc(uint32_t cl, unsigned int index) if (log_transaction) getpath_debug(src, lnode, pdata->active_only); } msm_bus_dbg_client_data(client->pdata, index , cl); trace_bus_update_request_end(pdata->name); exit_update_request: mutex_unlock(&msm_bus_adhoc_lock); return ret; } static void free_cl_mem(struct msm_bus_client_handle *cl) { if (cl) { kfree(cl->name); kfree(cl); cl = NULL; } } static int update_bw_adhoc(struct msm_bus_client_handle *cl, u64 ab, u64 ib) { int ret = 0; char *test_cl = "test-client"; bool log_transaction = false; mutex_lock(&msm_bus_adhoc_lock); if (!cl) { MSM_BUS_ERR("%s: Invalid client handle %p", __func__, cl); ret = -ENXIO; goto exit_update_request; } if (!strcmp(test_cl, cl->name)) log_transaction = true; msm_bus_dbg_rec_transaction(cl, ab, ib); if ((cl->cur_ib == ib) && (cl->cur_ab == ab)) { MSM_BUS_DBG("%s:no change in request", cl->name); goto exit_update_request; } ret = update_path(cl->mas, cl->slv, ib, ab, cl->cur_ib, cl->cur_ab, cl->first_hop, cl->active_only); if (ret) { MSM_BUS_ERR("%s: Update path failed! %d active_only %d\n", __func__, ret, cl->active_only); goto exit_update_request; } cl->cur_ib = ib; cl->cur_ab = ab; if (log_transaction) getpath_debug(cl->mas, cl->first_hop, cl->active_only); trace_bus_update_request_end(cl->name); exit_update_request: mutex_unlock(&msm_bus_adhoc_lock); return ret; } static void unregister_adhoc(struct msm_bus_client_handle *cl) { mutex_lock(&msm_bus_adhoc_lock); if (!cl) { MSM_BUS_ERR("%s: Null cl handle passed unregister\n", __func__); goto exit_unregister_client; } MSM_BUS_DBG("%s: Unregistering client %p", __func__, cl); remove_path(cl->mas, cl->slv, cl->cur_ib, cl->cur_ab, cl->first_hop, cl->active_only); msm_bus_dbg_remove_client(cl); kfree(cl); exit_unregister_client: mutex_unlock(&msm_bus_adhoc_lock); return; } static struct msm_bus_client_handle* register_adhoc(uint32_t mas, uint32_t slv, char *name, bool active_only) { struct msm_bus_client_handle *client = NULL; int len = 0; mutex_lock(&msm_bus_adhoc_lock); if (!(mas && slv && name)) { pr_err("%s: Error: src dst name num_paths are required", __func__); goto exit_register; } client = kzalloc(sizeof(struct msm_bus_client_handle), GFP_KERNEL); if (!client) { MSM_BUS_ERR("%s: Error allocating client data", __func__); goto exit_register; } len = strnlen(name, MAX_STR_CL); client->name = kzalloc(len, GFP_KERNEL); if (!client->name) { MSM_BUS_ERR("%s: Error allocating client name buf", __func__); free_cl_mem(client); goto exit_register; } strlcpy(client->name, name, MAX_STR_CL); client->active_only = active_only; client->mas = mas; client->slv = slv; client->first_hop = getpath(client->mas, client->slv); if (client->first_hop < 0) { MSM_BUS_ERR("%s:Failed to find path.src %d dest %d", __func__, client->mas, client->slv); free_cl_mem(client); goto exit_register; } MSM_BUS_DBG("%s:Client handle %p %s", __func__, client, client->name); msm_bus_dbg_add_client(client); exit_register: mutex_unlock(&msm_bus_adhoc_lock); return client; } /** * msm_bus_arb_setops_adhoc() : Setup the bus arbitration ops * @ arb_ops: pointer to the arb ops. Loading @@ -995,4 +1121,8 @@ void msm_bus_arb_setops_adhoc(struct msm_bus_arb_ops *arb_ops) arb_ops->register_client = register_client_adhoc; arb_ops->update_request = update_request_adhoc; arb_ops->unregister_client = unregister_client_adhoc; arb_ops->register_cl = register_adhoc; arb_ops->unregister = unregister_adhoc; arb_ops->update_bw = update_bw_adhoc; }
drivers/platform/msm/msm_bus/msm_bus_client_api.c +59 −0 Original line number Diff line number Diff line Loading @@ -81,3 +81,62 @@ void msm_bus_scale_unregister_client(uint32_t cl) } } EXPORT_SYMBOL(msm_bus_scale_unregister_client); /** * msm_bus_scale_register() - Register the clients with the msm bus * driver * @pdata: Platform data of the client, containing src, dest, ab, ib. * Return non-zero value in case of success, 0 in case of failure. * * Client data contains the vectors specifying arbitrated bandwidth (ab) * and instantaneous bandwidth (ib) requested between a particular * src and dest. */ struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, bool active_only) { if (arb_ops.register_cl) return arb_ops.register_cl(mas, slv, name, active_only); else { pr_err("%s: Bus driver not ready.", __func__); return ERR_PTR(-EPROBE_DEFER); } } EXPORT_SYMBOL(msm_bus_scale_register); /** * msm_bus_scale_client_update_bw() - Update the request for bandwidth * from a particular client * * cl: Handle to the client * index: Index into the vector, to which the bw and clock values need to be * updated */ int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) { if (arb_ops.update_request) return arb_ops.update_bw(cl, ab, ib); else { pr_err("%s: Bus driver not ready.", __func__); return -EPROBE_DEFER; } } EXPORT_SYMBOL(msm_bus_scale_update_bw); /** * msm_bus_scale_unregister() - Update the request for bandwidth * from a particular client * * cl: Handle to the client */ void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) { if (arb_ops.unregister) arb_ops.unregister(cl); else pr_err("%s: Bus driver not ready.", __func__); } EXPORT_SYMBOL(msm_bus_scale_unregister);
drivers/platform/msm/msm_bus/msm_bus_core.h +27 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,11 @@ struct msm_bus_arb_ops { uint32_t (*register_client)(struct msm_bus_scale_pdata *pdata); int (*update_request)(uint32_t cl, unsigned int index); void (*unregister_client)(uint32_t cl); struct msm_bus_client_handle* (*register_cl)(uint32_t mas, uint32_t slv, char *name, bool active_only); int (*update_bw)(struct msm_bus_client_handle *cl, u64 ab, u64 ib); void (*unregister)(struct msm_bus_client_handle *cl); }; enum { Loading Loading @@ -313,6 +318,11 @@ void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index, uint32_t cl); void msm_bus_dbg_commit_data(const char *fabname, void *cdata, int nmasters, int nslaves, int ntslaves, int op); int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata); int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata, u64 ab, u64 ib); void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata); #else static inline void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index, uint32_t cl) Loading @@ -323,6 +333,23 @@ static inline void msm_bus_dbg_commit_data(const char *fabname, int op) { } static inline void void msm_bus_dbg_remove_client (const struct msm_bus_client_handle *pdata) { } static inline int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata, u64 ab, u64 ib) { return 0; } static inline int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata) { return 0; } #endif #ifdef CONFIG_CORESIGHT Loading
drivers/platform/msm/msm_bus/msm_bus_dbg.c +94 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ struct msm_bus_dbg_state { struct msm_bus_cldata { const struct msm_bus_scale_pdata *pdata; const struct msm_bus_client_handle *handle; int index; uint32_t clid; int size; Loading Loading @@ -285,14 +286,17 @@ static ssize_t client_data_read(struct file *file, char __user *buf, int bsize = 0; uint32_t cl = (uint32_t)(uintptr_t)file->private_data; struct msm_bus_cldata *cldata = NULL; const struct msm_bus_client_handle *handle = file->private_data; int found = 0; list_for_each_entry(cldata, &cl_list, list) { if (cldata->clid == cl) { if ((cldata->clid == cl) || (cldata->handle && (cldata->handle == handle))) { found = 1; break; } } if (!found) return 0; Loading Loading @@ -323,6 +327,93 @@ struct dentry *msm_bus_dbg_create(const char *name, mode_t mode, &client_data_fops); } int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata) { struct msm_bus_cldata *cldata; cldata = kzalloc(sizeof(struct msm_bus_cldata), GFP_KERNEL); if (!cldata) { MSM_BUS_DBG("Failed to allocate memory for client data\n"); return -ENOMEM; } cldata->handle = pdata; list_add_tail(&cldata->list, &cl_list); return 0; } int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata, u64 ab, u64 ib) { struct msm_bus_cldata *cldata; int i; struct timespec ts; bool found = false; char *buf = NULL; list_for_each_entry(cldata, &cl_list, list) { if (cldata->handle == pdata) { found = true; break; } } if (!found) return -ENOENT; if (cldata->file == NULL) { if (pdata->name == NULL) { MSM_BUS_DBG("Client doesn't have a name\n"); return -EINVAL; } pr_err("\n%s setting up debugfs %s", __func__, pdata->name); cldata->file = debugfs_create_file(pdata->name, S_IRUGO, clients, (void *)pdata, &client_data_fops); } if (cldata->size < (MAX_BUFF_SIZE - FILL_LIMIT)) i = cldata->size; else { i = 0; cldata->size = 0; } buf = cldata->buffer; ts = ktime_to_timespec(ktime_get()); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n%d.%d\n", (int)ts.tv_sec, (int)ts.tv_nsec); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "master: "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ", pdata->mas); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nslave : "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ", pdata->slv); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nab : "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", ab); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nib : "); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", ib); i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n"); cldata->size = i; trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec, pdata->name, pdata->mas, pdata->slv, ab, ib); return i; } void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata) { struct msm_bus_cldata *cldata = NULL; list_for_each_entry(cldata, &cl_list, list) { if (cldata->handle == pdata) { debugfs_remove(cldata->file); list_del(&cldata->list); kfree(cldata); break; } } } static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata, int index, uint32_t clid, struct dentry *file) { Loading Loading @@ -416,12 +507,13 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata, for (j = 0; j < pdata->usecase->num_paths; j++) trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec, pdata->name, index, pdata->name, pdata->usecase[index].vectors[j].src, pdata->usecase[index].vectors[j].dst, pdata->usecase[index].vectors[j].ab, pdata->usecase[index].vectors[j].ib); cldata->index = index; cldata->size = i; return i; } Loading
include/linux/msm-bus.h +35 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,16 @@ struct msm_bus_scale_pdata { unsigned int active_only; }; struct msm_bus_client_handle { char *name; int mas; int slv; int first_hop; u64 cur_ib; u64 cur_ab; bool active_only; }; /* Scaling APIs */ /* Loading @@ -79,12 +89,19 @@ int __init msm_bus_fabric_init_driver(void); uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata); int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index); void msm_bus_scale_unregister_client(uint32_t cl); struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, bool active_only); void msm_bus_scale_unregister(struct msm_bus_client_handle *cl); int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); /* AXI Port configuration APIs */ int msm_bus_axi_porthalt(int master_port); int msm_bus_axi_portunhalt(int master_port); #else static inline int __init msm_bus_fabric_init_driver(void) { return 0; } static struct msm_bus_client_handle dummy_cl; static inline uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata) Loading Loading @@ -112,6 +129,24 @@ static inline int msm_bus_axi_portunhalt(int master_port) { return 0; } static inline struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, bool active_only) { return &dummy_cl; } static inline void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) { } static inline int msm_bus_scale_update_bw(uint32_t cl, u64 ab, u64 ib) { return 0; } #endif #if defined(CONFIG_OF) && defined(CONFIG_MSM_BUS_SCALING) Loading