Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ccfc186d authored by Girish Mahadevan's avatar Girish Mahadevan
Browse files

msm: msm_bus: Optimize the bus commit path



Optimize the bus commit path. Currently the driver iterates over all
devices during the aggregation portion of the transaction which can
be expensive depending on the size of the bus topology. Modified the
bus driver to allow iterating over only those devices whose bus
parent was affected by the current transaction.
Also don't commit the bus and bandwidth requests for each path
separately, rather do this at the end so that the driver doesn't end
up sending duplicate requests for resources common to different paths.

Change-Id: I346fb13c741a1baeea19d442a9722f78f1afdd13
Signed-off-by: default avatarGirish Mahadevan <girishm@codeaurora.org>
parent bf7a8985
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -136,16 +136,21 @@ struct msm_bus_node_device_type {
	uint32_t num_node_qos_clks;
	struct nodeclk *node_qos_clks;
	struct device_node *of_node;
	struct device dev;
	bool dirty;
	struct list_head dev_link;
	struct list_head devlist;
};

static inline struct msm_bus_node_device_type *to_msm_bus_node(struct device *d)
{
	return container_of(d, struct msm_bus_node_device_type, dev);
}


int msm_bus_enable_limiter(struct msm_bus_node_device_type *nodedev,
				int throttle_en, uint64_t lim_bw);
int msm_bus_update_clks(struct msm_bus_node_device_type *nodedev,
	int ctx, int **dirty_nodes, int *num_dirty);
int msm_bus_commit_data(int *dirty_nodes, int ctx, int num_dirty);
int msm_bus_update_bw(struct msm_bus_node_device_type *nodedev,
				int **dirty_nodes, int *num_dirty);
int msm_bus_commit_data(struct list_head *clist);
void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size,
					size_t new_size, gfp_t flags);

+116 −123
Original line number Diff line number Diff line
@@ -36,8 +36,9 @@ struct handle_type {
};

static struct handle_type handle_list;
struct list_head input_list;
struct list_head apply_list;
static LIST_HEAD(input_list);
static LIST_HEAD(apply_list);
static LIST_HEAD(commit_list);

DEFINE_MUTEX(msm_bus_adhoc_lock);

@@ -97,7 +98,7 @@ uint64_t msm_bus_div64(unsigned int w, uint64_t bw)
int msm_bus_device_match_adhoc(struct device *dev, void *id)
{
	int ret = 0;
	struct msm_bus_node_device_type *bnode = dev->platform_data;
	struct msm_bus_node_device_type *bnode = to_msm_bus_node(dev);

	if (bnode)
		ret = (bnode->node_info->id == *(unsigned int *)id);
@@ -117,7 +118,7 @@ static int gen_lnode(struct device *dev,
	if (!dev)
		goto exit_gen_lnode;

	cur_dev = dev->platform_data;
	cur_dev = to_msm_bus_node(dev);
	if (!cur_dev) {
		MSM_BUS_ERR("%s: Null device ptr", __func__);
		goto exit_gen_lnode;
@@ -293,25 +294,23 @@ static void setup_bl_list(struct msm_bus_node_device_type *node,

	for (i = 0; i < node->node_info->num_blist; i++) {
		struct msm_bus_node_device_type *bdev;
		bdev = node->node_info->black_connections[i]->platform_data;
		bdev = to_msm_bus_node(node->node_info->black_connections[i]);
		list_add_tail(&bdev->link, black_list);
	}
}

static int getpath(int src, int dest, const char *cl_name)
static int getpath(struct device *src_dev, int dest, const char *cl_name)
{
	struct list_head traverse_list;
	struct list_head edge_list;
	struct list_head route_list;
	struct list_head black_list;
	struct device *src_dev = bus_find_device(&msm_bus_type, NULL,
					(void *) &src,
					msm_bus_device_match_adhoc);
	struct msm_bus_node_device_type *src_node;
	struct bus_search_type *search_node;
	int found = 0;
	int depth_index = 0;
	int first_hop = -1;
	int src;

	INIT_LIST_HEAD(&traverse_list);
	INIT_LIST_HEAD(&edge_list);
@@ -319,15 +318,16 @@ static int getpath(int src, int dest, const char *cl_name)
	INIT_LIST_HEAD(&black_list);

	if (!src_dev) {
		MSM_BUS_ERR("%s: Cannot locate src dev %d", __func__, src);
		MSM_BUS_ERR("%s: Cannot locate src dev ", __func__);
		goto exit_getpath;
	}

	src_node = src_dev->platform_data;
	src_node = to_msm_bus_node(src_dev);
	if (!src_node) {
		MSM_BUS_ERR("%s:Fatal, Source dev %d not found", __func__, src);
		MSM_BUS_ERR("%s:Fatal, Source node not found", __func__);
		goto exit_getpath;
	}
	src = src_node->node_info->id;
	list_add_tail(&src_node->link, &traverse_list);

	while ((!found && !list_empty(&traverse_list))) {
@@ -352,9 +352,9 @@ static int getpath(int src, int dest, const char *cl_name)
					bool skip;
					struct msm_bus_node_device_type
							*node_conn;
					node_conn = bus_node->node_info->
						dev_connections[i]->
						platform_data;
					node_conn =
					to_msm_bus_node(bus_node->node_info->
						dev_connections[i]);
					if (node_conn->node_info->
							is_traversed) {
						MSM_BUS_ERR("Circ Path %d\n",
@@ -551,12 +551,12 @@ static uint64_t aggregate_bus_req(struct msm_bus_node_device_type *bus_dev,
	uint64_t max_ib = 0;
	uint64_t sum_ab = 0;

	if (!bus_dev || !bus_dev->node_info->bus_device->platform_data) {
	if (!bus_dev || !to_msm_bus_node(bus_dev->node_info->bus_device)) {
		MSM_BUS_ERR("Bus node pointer is Invalid");
		goto exit_agg_bus_req;
	}

	fab_dev = bus_dev->node_info->bus_device->platform_data;
	fab_dev = to_msm_bus_node(bus_dev->node_info->bus_device);
	for (i = 0; i < bus_dev->num_lnodes; i++) {
		max_ib = max(max_ib, bus_dev->lnode_list[i].lnode_ib[ctx]);
		sum_ab += bus_dev->lnode_list[i].lnode_ab[ctx];
@@ -591,8 +591,10 @@ static void del_inp_list(struct list_head *list)
	struct rule_update_path_info *rule_node;
	struct rule_update_path_info *rule_node_tmp;

	list_for_each_entry_safe(rule_node, rule_node_tmp, list, link)
	list_for_each_entry_safe(rule_node, rule_node_tmp, list, link) {
		list_del(&rule_node->link);
		rule_node->added = false;
	}
}

static void del_op_list(struct list_head *list)
@@ -626,7 +628,7 @@ static int msm_bus_apply_rules(struct list_head *list, bool after_clk_commit)
			MSM_BUS_ERR("Can't find dev node for %d", rule->id);
			continue;
		}
		dev_info = dev->platform_data;
		dev_info = to_msm_bus_node(dev);

		ret = msm_bus_enable_limiter(dev_info, rule->throttle,
							rule->lim_bw);
@@ -637,65 +639,58 @@ static int msm_bus_apply_rules(struct list_head *list, bool after_clk_commit)
	return ret;
}

static uint64_t get_node_aggab(struct msm_bus_node_device_type *bus_dev)
static void commit_data(void)
{
	int i;
	int ctx;
	uint64_t max_agg_ab = 0;
	uint64_t agg_ab = 0;
	bool rules_registered = msm_rule_are_rules_registered();

	for (ctx = 0; ctx < NUM_CTX; ctx++) {
		for (i = 0; i < bus_dev->num_lnodes; i++)
			agg_ab += bus_dev->lnode_list[i].lnode_ab[ctx];
	if (rules_registered) {
		msm_rules_update_path(&input_list, &apply_list);
		msm_bus_apply_rules(&apply_list, false);
	}

		if (bus_dev->node_info->agg_params.num_aggports > 1)
			agg_ab =
			msm_bus_div64(
				bus_dev->node_info->agg_params.num_aggports,
				agg_ab);
	msm_bus_commit_data(&commit_list);

		max_agg_ab = max(max_agg_ab, agg_ab);
	if (rules_registered) {
		msm_bus_apply_rules(&apply_list, true);
		del_inp_list(&input_list);
		del_op_list(&apply_list);
	}

	return max_agg_ab;
	INIT_LIST_HEAD(&input_list);
	INIT_LIST_HEAD(&apply_list);
	INIT_LIST_HEAD(&commit_list);
}

static uint64_t get_node_ib(struct msm_bus_node_device_type *bus_dev)
static void add_node_to_clist(struct msm_bus_node_device_type *node)
{
	int i;
	int ctx;
	uint64_t max_ib = 0;
	struct msm_bus_node_device_type *node_parent =
			to_msm_bus_node(node->node_info->bus_device);

	for (ctx = 0; ctx < NUM_CTX; ctx++) {
		for (i = 0; i < bus_dev->num_lnodes; i++)
			max_ib = max(max_ib,
				bus_dev->lnode_list[i].lnode_ib[ctx]);
	if (!node->dirty) {
		list_add_tail(&node->link, &commit_list);
		node->dirty = true;
	}

	if (!node_parent->dirty) {
		list_add_tail(&node_parent->link, &commit_list);
		node_parent->dirty = true;
	}
	return max_ib;
}

static int update_path(int src, int dest, uint64_t act_req_ib,
static int update_path(struct device *src_dev, int dest, uint64_t act_req_ib,
			uint64_t act_req_bw, uint64_t slp_req_ib,
			uint64_t slp_req_bw, uint64_t cur_ib, uint64_t cur_bw,
			int src_idx, int ctx)
{
	struct device *src_dev = NULL;
	struct device *next_dev = NULL;
	struct link_node *lnode = NULL;
	struct msm_bus_node_device_type *dev_info = NULL;
	int curr_idx;
	int ret = 0;
	int *dirty_nodes = NULL;
	int num_dirty = 0;
	struct rule_update_path_info *rule_node;
	bool rules_registered = msm_rule_are_rules_registered();

	src_dev = bus_find_device(&msm_bus_type, NULL,
				(void *) &src,
				msm_bus_device_match_adhoc);

	if (!src_dev) {
		MSM_BUS_ERR("%s: Can't find source device %d", __func__, src);
	if (IS_ERR_OR_NULL(src_dev)) {
		MSM_BUS_ERR("%s: No source device", __func__);
		ret = -ENODEV;
		goto exit_update_path;
	}
@@ -709,12 +704,9 @@ static int update_path(int src, int dest, uint64_t act_req_ib,
	}
	curr_idx = src_idx;

	INIT_LIST_HEAD(&input_list);
	INIT_LIST_HEAD(&apply_list);

	while (next_dev) {
		int i;
		dev_info = next_dev->platform_data;
		dev_info = to_msm_bus_node(next_dev);

		if (curr_idx >= dev_info->num_lnodes) {
			MSM_BUS_ERR("%s: Invalid lnode Idx %d num lnodes %d",
@@ -739,62 +731,32 @@ static int update_path(int src, int dest, uint64_t act_req_ib,
			dev_info->node_bw[i].cur_clk_hz =
					aggregate_bus_req(dev_info, i);

		/* Start updating the clocks at the first hop.
		 * Its ok to figure out the aggregated
		 * request at this node.
		 */
		if (src_dev != next_dev) {
			ret = msm_bus_update_clks(dev_info, ctx, &dirty_nodes,
								&num_dirty);
			if (ret) {
				MSM_BUS_ERR("%s: Failed to update clks dev %d",
					__func__, dev_info->node_info->id);
				goto exit_update_path;
			}
		}

		ret = msm_bus_update_bw(dev_info, &dirty_nodes, &num_dirty);
		if (ret) {
			MSM_BUS_ERR("%s: Failed to update bw dev %d",
				__func__, dev_info->node_info->id);
			goto exit_update_path;
		}
		add_node_to_clist(dev_info);

		if (rules_registered) {
			rule_node = &dev_info->node_info->rule;
			rule_node->id = dev_info->node_info->id;
			rule_node->ib = get_node_ib(dev_info);
			rule_node->ab = get_node_aggab(dev_info);
			rule_node->ib = dev_info->node_bw[ACTIVE_CTX].max_ib;
			rule_node->ab = dev_info->node_bw[ACTIVE_CTX].sum_ab;
			rule_node->clk =
				max(dev_info->node_bw[ACTIVE_CTX].cur_clk_hz,
					dev_info->node_bw[DUAL_CTX].cur_clk_hz);
				dev_info->node_bw[ACTIVE_CTX].cur_clk_hz;
			if (!rule_node->added) {
				list_add_tail(&rule_node->link, &input_list);
				rule_node->added = true;
			}
		}

		next_dev = lnode->next_dev;
		curr_idx = lnode->next;
	}

	if (rules_registered) {
		msm_rules_update_path(&input_list, &apply_list);
		msm_bus_apply_rules(&apply_list, false);
	}

	msm_bus_commit_data(dirty_nodes, ctx, num_dirty);

	if (rules_registered) {
		msm_bus_apply_rules(&apply_list, true);
		del_inp_list(&input_list);
		del_op_list(&apply_list);
	}
exit_update_path:
	return ret;
}

static int remove_path(int src, int dst, uint64_t cur_ib, uint64_t cur_ab,
				int src_idx, int active_only)
static int remove_path(struct device *src_dev, int dst, uint64_t cur_ib,
			uint64_t cur_ab, int src_idx, int active_only)
{
	struct device *src_dev = NULL;
	struct device *next_dev = NULL;
	struct link_node *lnode = NULL;
	struct msm_bus_node_device_type *dev_info = NULL;
@@ -805,8 +767,13 @@ static int remove_path(int src, int dst, uint64_t cur_ib, uint64_t cur_ab,
	/* Update the current path to zero out all request from
	 * this cient on all paths
	 */
	if (!src_dev) {
		MSM_BUS_ERR("%s: Can't find source device", __func__);
		ret = -ENODEV;
		goto exit_remove_path;
	}

	ret = update_path(src, dst, 0, 0, 0, 0, cur_ib, cur_ab, src_idx,
	ret = update_path(src_dev, dst, 0, 0, 0, 0, cur_ib, cur_ab, src_idx,
							active_only);
	if (ret) {
		MSM_BUS_ERR("%s: Error zeroing out path ctx %d",
@@ -814,19 +781,10 @@ static int remove_path(int src, int dst, uint64_t cur_ib, uint64_t cur_ab,
		goto exit_remove_path;
	}

	src_dev = bus_find_device(&msm_bus_type, NULL,
				(void *) &src,
				msm_bus_device_match_adhoc);
	if (!src_dev) {
		MSM_BUS_ERR("%s: Can't find source device %d", __func__, src);
		ret = -ENODEV;
		goto exit_remove_path;
	}

	next_dev = src_dev;

	while (next_dev) {
		dev_info = next_dev->platform_data;
		dev_info = to_msm_bus_node(next_dev);
		lnode = &dev_info->lnode_list[cur_idx];
		next_idx = lnode->next;
		next_dev = lnode->next_dev;
@@ -857,13 +815,13 @@ static void getpath_debug(int src, int curr, int active_only)
	}

	idx = curr;
	devinfo = dev_node->platform_data;
	devinfo = to_msm_bus_node(dev_node);
	dev_it = dev_node;

	MSM_BUS_ERR("Route list Src %d", src);
	while (dev_it) {
		struct msm_bus_node_device_type *busdev =
			devinfo->node_info->bus_device->platform_data;
			to_msm_bus_node(devinfo->node_info->bus_device);

		MSM_BUS_ERR("Hop[%d] at Device %d ctx %d", hop,
					devinfo->node_info->id, active_only);
@@ -878,7 +836,7 @@ static void getpath_debug(int src, int curr, int active_only)
		dev_it = devinfo->lnode_list[idx].next_dev;
		idx = devinfo->lnode_list[idx].next;
		if (dev_it)
			devinfo = dev_it->platform_data;
			devinfo = to_msm_bus_node(dev_it);

		MSM_BUS_ERR("Bus Device %d", busdev->node_info->id);
		MSM_BUS_ERR("Bus Clock %llu", busdev->clk[active_only].rate);
@@ -896,6 +854,7 @@ static void unregister_client_adhoc(uint32_t cl)
	int lnode, src, curr, dest;
	uint64_t  cur_clk, cur_bw;
	struct msm_bus_client *client;
	struct device *src_dev;

	mutex_lock(&msm_bus_adhoc_lock);
	if (!cl) {
@@ -924,11 +883,13 @@ static void unregister_client_adhoc(uint32_t cl)
		dest = client->pdata->usecase[curr].vectors[i].dst;

		lnode = client->src_pnode[i];
		src_dev = client->src_devs[i];
		cur_clk = client->pdata->usecase[curr].vectors[i].ib;
		cur_bw = client->pdata->usecase[curr].vectors[i].ab;
		remove_path(src, dest, cur_clk, cur_bw, lnode,
		remove_path(src_dev, dest, cur_clk, cur_bw, lnode,
						pdata->active_only);
	}
	commit_data();
	msm_bus_dbg_client_data(client->pdata, MSM_BUS_DBG_UNREGISTER, cl);
	kfree(client->src_pnode);
	kfree(client);
@@ -1009,6 +970,7 @@ static uint32_t register_client_adhoc(struct msm_bus_scale_pdata *pdata)
	int i;
	struct msm_bus_client *client = NULL;
	int *lnode;
	struct device *dev;
	uint32_t handle = 0;

	mutex_lock(&msm_bus_adhoc_lock);
@@ -1025,6 +987,13 @@ static uint32_t register_client_adhoc(struct msm_bus_scale_pdata *pdata)
		goto exit_register_client;
	}
	client->src_pnode = lnode;

	client->src_devs = kzalloc(pdata->usecase->num_paths *
					sizeof(struct device *), GFP_KERNEL);
	if (IS_ERR_OR_NULL(client->src_devs)) {
		MSM_BUS_ERR("%s: Error allocating pathnode ptr!", __func__);
		goto exit_register_client;
	}
	client->curr = -1;

	for (i = 0; i < pdata->usecase->num_paths; i++) {
@@ -1036,8 +1005,17 @@ static uint32_t register_client_adhoc(struct msm_bus_scale_pdata *pdata)
				__func__, src, dest);
			goto exit_register_client;
		}
		dev = bus_find_device(&msm_bus_type, NULL,
				(void *) &src,
				msm_bus_device_match_adhoc);
		if (IS_ERR_OR_NULL(dev)) {
			MSM_BUS_ERR("%s:Failed to find path.src %d dest %d",
				__func__, src, dest);
			goto exit_register_client;
		}
		client->src_devs[i] = dev;

		lnode[i] = getpath(src, dest, client->pdata->name);
		lnode[i] = getpath(dev, dest, client->pdata->name);
		if (lnode[i] < 0) {
			MSM_BUS_ERR("%s:Failed to find path.src %d dest %d",
				__func__, src, dest);
@@ -1062,6 +1040,7 @@ static int update_client_paths(struct msm_bus_client *client, bool log_trns,
	uint64_t req_clk, req_bw, curr_clk, curr_bw, slp_clk, slp_bw;
	int i, ret = 0;
	struct msm_bus_scale_pdata *pdata;
	struct device *src_dev;

	if (!client) {
		MSM_BUS_ERR("Client handle  Null");
@@ -1083,6 +1062,7 @@ static int update_client_paths(struct msm_bus_client *client, bool log_trns,
		dest = pdata->usecase[idx].vectors[i].dst;

		lnode = client->src_pnode[i];
		src_dev = client->src_devs[i];
		req_clk = client->pdata->usecase[idx].vectors[i].ib;
		req_bw = client->pdata->usecase[idx].vectors[i].ab;
		if (cur_idx < 0) {
@@ -1104,18 +1084,19 @@ static int update_client_paths(struct msm_bus_client *client, bool log_trns,
			slp_bw = req_bw;
		}

		ret = update_path(src, dest, req_clk, req_bw, slp_clk, slp_bw,
				curr_clk, curr_bw, lnode, pdata->active_only);
		ret = update_path(src_dev, dest, req_clk, req_bw, slp_clk,
			slp_bw, curr_clk, curr_bw, lnode, pdata->active_only);

		if (ret) {
			MSM_BUS_ERR("%s: Update path failed! %d ctx %d\n",
					__func__, ret, ACTIVE_CTX);
					__func__, ret, pdata->active_only);
			goto exit_update_client_paths;
		}

		if (log_trns)
			getpath_debug(src, lnode, pdata->active_only);
	}
	commit_data();
exit_update_client_paths:
	return ret;
}
@@ -1280,7 +1261,7 @@ static int update_bw_adhoc(struct msm_bus_client_handle *cl, u64 ab, u64 ib)
		slp_ab = ab;
	}

	ret = update_path(cl->mas, cl->slv, ib, ab, slp_ib, slp_ab,
	ret = update_path(cl->mas_dev, cl->slv, ib, ab, slp_ib, slp_ab,
		cl->cur_act_ib, cl->cur_act_ab, cl->first_hop, cl->active_only);

	if (ret) {
@@ -1289,6 +1270,7 @@ static int update_bw_adhoc(struct msm_bus_client_handle *cl, u64 ab, u64 ib)
		goto exit_update_request;
	}

	commit_data();
	cl->cur_act_ib = ib;
	cl->cur_act_ab = ab;
	cl->cur_slp_ib = slp_ib;
@@ -1326,7 +1308,7 @@ static int update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab,
	if (!slp_ab && !slp_ib)
		cl->active_only = true;
	msm_bus_dbg_rec_transaction(cl, cl->cur_act_ab, cl->cur_slp_ib);
	ret = update_path(cl->mas, cl->slv, act_ib, act_ab, slp_ib, slp_ab,
	ret = update_path(cl->mas_dev, cl->slv, act_ib, act_ab, slp_ib, slp_ab,
				cl->cur_act_ab, cl->cur_act_ab,  cl->first_hop,
				cl->active_only);
	if (ret) {
@@ -1334,7 +1316,7 @@ static int update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab,
				__func__, ret, cl->active_only);
		goto exit_change_context;
	}

	commit_data();
	cl->cur_act_ib = act_ib;
	cl->cur_act_ab = act_ab;
	cl->cur_slp_ib = slp_ib;
@@ -1356,9 +1338,9 @@ static void unregister_adhoc(struct msm_bus_client_handle *cl)

	MSM_BUS_DBG("%s: Unregistering client %p", __func__, cl);

	remove_path(cl->mas, cl->slv, cl->cur_act_ib, cl->cur_act_ab,
	remove_path(cl->mas_dev, cl->slv, cl->cur_act_ib, cl->cur_act_ab,
				cl->first_hop, cl->active_only);

	commit_data();
	msm_bus_dbg_remove_client(cl);
	kfree(cl);
exit_unregister_client:
@@ -1398,7 +1380,18 @@ register_adhoc(uint32_t mas, uint32_t slv, char *name, bool active_only)

	client->mas = mas;
	client->slv = slv;
	client->first_hop = getpath(client->mas, client->slv, client->name);

	client->mas_dev = bus_find_device(&msm_bus_type, NULL,
					(void *) &mas,
					msm_bus_device_match_adhoc);
	if (IS_ERR_OR_NULL(client->mas_dev)) {
		MSM_BUS_ERR("%s:Failed to find path.src %d dest %d",
			__func__, client->mas, client->slv);
		free_cl_mem(client);
		goto exit_register;
	}

	client->first_hop = getpath(client->mas_dev, client->slv, client->name);
	if (client->first_hop < 0) {
		MSM_BUS_ERR("%s:Failed to find path.src %d dest %d",
			__func__, client->mas, client->slv);
+1 −0
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ struct msm_bus_client {
	struct msm_bus_scale_pdata *pdata;
	int *src_pnode;
	int curr;
	struct device **src_devs;
};

uint64_t msm_bus_div64(unsigned int width, uint64_t bw);
+31 −72
Original line number Diff line number Diff line
@@ -154,36 +154,36 @@ static DEVICE_ATTR(floor_vote_api, S_IRUGO | S_IWUSR,
static DEVICE_ATTR(floor_active_only, S_IRUGO | S_IWUSR,
		bus_floor_active_only_show, bus_floor_active_only_store);

static int msm_bus_floor_init_dev(struct device *fab_dev,
				struct device *dev, bool is_master)
static struct msm_bus_node_device_type *msm_bus_floor_init_dev(
				struct device *fab_dev, bool is_master)
{
	struct msm_bus_node_device_type *bus_node = NULL;
	struct msm_bus_node_device_type *fab_node = NULL;
	struct msm_bus_node_info_type *node_info = NULL;
	struct device *dev = NULL;
	int ret = 0;

	if (!(fab_dev && dev)) {
		ret = -ENXIO;
	if (!fab_dev) {
		bus_node = ERR_PTR(-ENXIO);
		goto exit_init_bus_dev;
	}

	fab_node = fab_dev->platform_data;
	fab_node = to_msm_bus_node(fab_dev);

	if (!fab_node) {
		pr_info("\n%s: Can't create device", __func__);
		ret = -ENXIO;
		bus_node = ERR_PTR(-ENXIO);
		goto exit_init_bus_dev;
	}

	device_initialize(dev);
	bus_node = devm_kzalloc(dev,
		sizeof(struct msm_bus_node_device_type), GFP_KERNEL);

	bus_node = kzalloc(sizeof(struct msm_bus_node_device_type), GFP_KERNEL);
	if (!bus_node) {
		pr_err("%s:Bus node alloc failed\n", __func__);
		ret = -ENOMEM;
		bus_node = ERR_PTR(-ENOMEM);
		goto exit_init_bus_dev;
	}
	dev = &bus_node->dev;
	device_initialize(dev);

	node_info = devm_kzalloc(dev,
		sizeof(struct msm_bus_node_info_type), GFP_KERNEL);
@@ -191,7 +191,7 @@ static int msm_bus_floor_init_dev(struct device *fab_dev,
	if (!node_info) {
		pr_err("%s:Bus node info alloc failed\n", __func__);
		devm_kfree(dev, bus_node);
		ret = -ENOMEM;
		bus_node = ERR_PTR(-ENOMEM);
		goto exit_init_bus_dev;
	}

@@ -199,14 +199,14 @@ static int msm_bus_floor_init_dev(struct device *fab_dev,
	bus_node->ap_owned = true;
	bus_node->node_info->bus_device = fab_dev;
	bus_node->node_info->agg_params.buswidth = 8;
	dev->platform_data = bus_node;
	dev->bus = &msm_bus_type;
	list_add_tail(&bus_node->dev_link, &fab_node->devlist);

	bus_node->node_info->id = get_id();
	if (bus_node->node_info->id < 0) {
		pr_err("%s: Failed to get id for dev. Bus:%s is_master:%d",
			__func__, fab_node->node_info->name, is_master);
		ret = -ENXIO;
		bus_node = ERR_PTR(-ENXIO);
		goto exit_init_bus_dev;
	}

@@ -216,11 +216,12 @@ static int msm_bus_floor_init_dev(struct device *fab_dev,
	ret = device_add(dev);
	if (ret < 0) {
		pr_err("%s: Failed to add %s", __func__, dev_name(dev));
		bus_node = ERR_PTR(ret);
		goto exit_init_bus_dev;
	}

exit_init_bus_dev:
	return ret;
	return bus_node;
}

static int msm_bus_floor_show_info(struct device *dev, void *data)
@@ -371,30 +372,22 @@ exit_bus_floor_vote_context:
}
EXPORT_SYMBOL(msm_bus_floor_vote_context);

static int msm_bus_floor_setup_dev_conn(struct device *mas, struct device *slv)
static int msm_bus_floor_setup_dev_conn(
		struct msm_bus_node_device_type *mas_node,
		struct msm_bus_node_device_type *slv_node)
{
	int ret = 0;
	int slv_id = 0;
	struct msm_bus_node_device_type *mas_node = NULL;
	struct msm_bus_node_device_type *slv_node = NULL;

	if (!(mas && slv)) {
		pr_err("\n%s: Invalid master/slave device", __func__);
		ret = -ENXIO;
		goto exit_setup_dev_conn;
	}

	mas_node = mas->platform_data;
	slv_node = slv->platform_data;

	if (!(mas_node && slv_node)) {
		pr_err("\n%s: Invalid master/slave device", __func__);
		ret = -ENXIO;
		goto exit_setup_dev_conn;
	}

	slv_id = slv_node->node_info->id;
	mas_node->node_info->num_connections = 1;
	mas_node->node_info->connections = devm_kzalloc(mas,
	mas_node->node_info->connections = devm_kzalloc(&mas_node->dev,
			(sizeof(int) * mas_node->node_info->num_connections),
			GFP_KERNEL);

@@ -404,7 +397,7 @@ static int msm_bus_floor_setup_dev_conn(struct device *mas, struct device *slv)
		goto exit_setup_dev_conn;
	}

	mas_node->node_info->dev_connections = devm_kzalloc(mas,
	mas_node->node_info->dev_connections = devm_kzalloc(&mas_node->dev,
			(sizeof(struct device *) *
				mas_node->node_info->num_connections),
			GFP_KERNEL);
@@ -416,7 +409,7 @@ static int msm_bus_floor_setup_dev_conn(struct device *mas, struct device *slv)
		goto exit_setup_dev_conn;
	}
	mas_node->node_info->connections[0] = slv_id;
	mas_node->node_info->dev_connections[0] = slv;
	mas_node->node_info->dev_connections[0] = &slv_node->dev;

exit_setup_dev_conn:
	return ret;
@@ -499,8 +492,6 @@ err_setup_floor_dev:

int msm_bus_floor_init(struct device *dev)
{
	struct device *m_dev = NULL;
	struct device *s_dev = NULL;
	struct msm_bus_node_device_type *mas_node = NULL;
	struct msm_bus_node_device_type *slv_node = NULL;
	struct msm_bus_node_device_type *bus_node = NULL;
@@ -512,7 +503,7 @@ int msm_bus_floor_init(struct device *dev)
		goto exit_floor_init;
	}

	bus_node = dev->platform_data;
	bus_node = to_msm_bus_node(dev);
	if (!(bus_node && bus_node->node_info->is_fab_dev)) {
		pr_info("\n%s: Can't create voting client, not a fab device",
								__func__);
@@ -520,57 +511,27 @@ int msm_bus_floor_init(struct device *dev)
		goto exit_floor_init;
	}

	m_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
	if (!m_dev) {
		pr_err("%s:Master Device alloc failed\n", __func__);
		m_dev = NULL;
		ret = -ENOMEM;
		goto exit_floor_init;
	}

	s_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
	if (!m_dev) {
		pr_err("%s:Slave Device alloc failed\n", __func__);
		s_dev = NULL;
		kfree(m_dev);
		ret = -ENOMEM;
		m_dev = NULL;
		goto exit_floor_init;
	}

	ret = msm_bus_floor_init_dev(dev, m_dev, true);
	if (ret) {
	mas_node = msm_bus_floor_init_dev(dev, true);
	if (IS_ERR_OR_NULL(mas_node)) {
		pr_err("\n%s: Error setting up master dev, bus %d",
					__func__, bus_node->node_info->id);
		kfree(m_dev);
		kfree(s_dev);
		goto exit_floor_init;
	}

	ret = msm_bus_floor_init_dev(dev, s_dev, false);
	if (ret) {
	slv_node = msm_bus_floor_init_dev(dev, false);
	if (IS_ERR_OR_NULL(slv_node)) {
		pr_err("\n%s: Error setting up slave dev, bus %d",
					__func__, bus_node->node_info->id);
		kfree(m_dev);
		kfree(s_dev);
		goto exit_floor_init;
	}

	ret = msm_bus_floor_setup_dev_conn(m_dev, s_dev);
	ret = msm_bus_floor_setup_dev_conn(mas_node, slv_node);
	if (ret) {
		pr_err("\n%s: Error setting up connections bus %d",
					__func__, bus_node->node_info->id);
		goto err_floor_init;
	}

	mas_node = m_dev->platform_data;
	slv_node = s_dev->platform_data;
	if ((!(mas_node && slv_node))) {
		pr_err("\n%s: Error getting mas/slv nodes bus %d",
					__func__, bus_node->node_info->id);
		goto err_floor_init;
	}

	ret = msm_bus_floor_setup_floor_dev(mas_node, slv_node, bus_node);
	if (ret) {
		pr_err("\n%s: Error getting mas/slv nodes bus %d",
@@ -581,9 +542,7 @@ int msm_bus_floor_init(struct device *dev)
exit_floor_init:
	return ret;
err_floor_init:
	device_unregister(m_dev);
	device_unregister(s_dev);
	kfree(m_dev);
	kfree(s_dev);
	kfree(mas_node);
	kfree(slv_node);
	return ret;
}
+116 −308

File changed.

Preview size limit exceeded, changes collapsed.

Loading