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

Commit 559858c9 authored by Odelu Kukatla's avatar Odelu Kukatla Committed by Gerrit - the friendly Code Review server
Browse files

msm: msm_bus: Clean up the bus scaling driver



Fix the compilation errors and add error logging for
memory allocation failures.
Also change the driver init level to fs_initcall as
clock driver is probed at subsys_initcall level.

Change-Id: I928be84eb10e3ab511efec621f2edc2c3e675d8c
Signed-off-by: default avatarOdelu Kukatla <okukatla@codeaurora.org>
parent 630e89aa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ ifdef CONFIG_QCOM_BUS_CONFIG_RPMH
		msm_bus_bimc_rpmh.o msm_bus_noc_rpmh.o
	obj-$(CONFIG_OF) += msm_bus_of_rpmh.o
else
	obj-y += msm_bus_fabric_adhoc.o msm_bus_arb_adhoc.o \
	obj-y += msm_bus_fabric_adhoc.o msm_bus_arb_adhoc.o msm_bus_rules.o \
		msm_bus_bimc_adhoc.o msm_bus_noc_adhoc.o
	obj-$(CONFIG_OF) += msm_bus_of_adhoc.o
endif
+37 −107
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -73,26 +73,26 @@ static void copy_remaining_nodes(struct list_head *edge_list, struct list_head
 * "util" file for these common func/macros.
 *
 */
uint64_t msm_bus_div64(unsigned int w, uint64_t bw)
uint64_t msm_bus_div64(uint64_t num, unsigned int base)
{
	uint64_t *b = &bw;
	uint64_t *n = &num;

	if ((bw > 0) && (bw < w))
	if ((num > 0) && (num < base))
		return 1;

	switch (w) {
	switch (base) {
	case 0:
		WARN(1, "AXI: Divide by 0 attempted\n");
	case 1: return bw;
	case 2: return (bw >> 1);
	case 4: return (bw >> 2);
	case 8: return (bw >> 3);
	case 16: return (bw >> 4);
	case 32: return (bw >> 5);
	case 1: return num;
	case 2: return (num >> 1);
	case 4: return (num >> 2);
	case 8: return (num >> 3);
	case 16: return (num >> 4);
	case 32: return (num >> 5);
	}

	do_div(*b, w);
	return *b;
	do_div(*n, base);
	return *n;
}

int msm_bus_device_match_adhoc(struct device *dev, void *id)
@@ -452,19 +452,18 @@ static uint64_t scheme1_agg_scheme(struct msm_bus_node_device_type *bus_dev,

	if (util_fact && (util_fact != 100)) {
		sum_ab *= util_fact;
		sum_ab = msm_bus_div64(100, sum_ab);
		sum_ab = msm_bus_div64(sum_ab, 100);
	}

	if (vrail_comp && (vrail_comp != 100)) {
		max_ib *= 100;
		max_ib = msm_bus_div64(vrail_comp, max_ib);
		max_ib = msm_bus_div64(max_ib, vrail_comp);
	}

	/* Account for multiple channels if any */
	if (bus_dev->node_info->agg_params.num_aggports > 1)
		sum_ab = msm_bus_div64(
				bus_dev->node_info->agg_params.num_aggports,
					sum_ab);
		sum_ab = msm_bus_div64(sum_ab,
				bus_dev->node_info->agg_params.num_aggports);

	if (!bus_dev->node_info->agg_params.buswidth) {
		MSM_BUS_WARN("No bus width found for %d. Using default\n",
@@ -473,8 +472,8 @@ static uint64_t scheme1_agg_scheme(struct msm_bus_node_device_type *bus_dev,
	}

	bw_max_hz = max(max_ib, sum_ab);
	bw_max_hz = msm_bus_div64(bus_dev->node_info->agg_params.buswidth,
					bw_max_hz);
	bw_max_hz = msm_bus_div64(bw_max_hz,
				bus_dev->node_info->agg_params.buswidth);

	return bw_max_hz;
}
@@ -517,19 +516,18 @@ static uint64_t legacy_agg_scheme(struct msm_bus_node_device_type *bus_dev,

	if (util_fact && (util_fact != 100)) {
		sum_ab *= util_fact;
		sum_ab = msm_bus_div64(100, sum_ab);
		sum_ab = msm_bus_div64(sum_ab, 100);
	}

	if (vrail_comp && (vrail_comp != 100)) {
		max_ib *= 100;
		max_ib = msm_bus_div64(vrail_comp, max_ib);
		max_ib = msm_bus_div64(max_ib, vrail_comp);
	}

	/* Account for multiple channels if any */
	if (bus_dev->node_info->agg_params.num_aggports > 1)
		sum_ab = msm_bus_div64(
				bus_dev->node_info->agg_params.num_aggports,
					sum_ab);
		sum_ab = msm_bus_div64(sum_ab,
				bus_dev->node_info->agg_params.num_aggports);

	if (!bus_dev->node_info->agg_params.buswidth) {
		MSM_BUS_WARN("No bus width found for %d. Using default\n",
@@ -538,8 +536,8 @@ static uint64_t legacy_agg_scheme(struct msm_bus_node_device_type *bus_dev,
	}

	bw_max_hz = max(max_ib, sum_ab);
	bw_max_hz = msm_bus_div64(bus_dev->node_info->agg_params.buswidth,
					bw_max_hz);
	bw_max_hz = msm_bus_div64(bw_max_hz,
				bus_dev->node_info->agg_params.buswidth);

	return bw_max_hz;
}
@@ -873,7 +871,7 @@ static void unregister_client_adhoc(uint32_t cl)
	}

	curr = client->curr;
	if (curr >= pdata->num_usecases) {
	if ((curr < 0) || (curr >= pdata->num_usecases)) {
		MSM_BUS_ERR("Invalid index Defaulting curr to 0");
		curr = 0;
	}
@@ -1111,75 +1109,6 @@ static int update_client_paths(struct msm_bus_client *client, bool log_trns,
	return ret;
}

static int query_client_paths(struct msm_bus_client *client, bool log_trns,
							unsigned int idx)
{
	int lnode, src, dest, cur_idx;
	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");
		ret = -ENXIO;
		goto exit_update_client_paths;
	}

	pdata = client->pdata;
	if (!pdata) {
		MSM_BUS_ERR("Client pdata Null");
		ret = -ENXIO;
		goto exit_update_client_paths;
	}

	cur_idx = client->curr;
	client->curr = idx;
	for (i = 0; i < pdata->usecase->num_paths; i++) {
		src = pdata->usecase[idx].vectors[i].src;
		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) {
			curr_clk = 0;
			curr_bw = 0;
		} else {
			curr_clk =
				client->pdata->usecase[cur_idx].vectors[i].ib;
			curr_bw = client->pdata->usecase[cur_idx].vectors[i].ab;
			MSM_BUS_DBG("%s:ab: %llu ib: %llu\n", __func__,
					curr_bw, curr_clk);
		}

		if (pdata->active_only) {
			slp_clk = 0;
			slp_bw = 0;
		} else {
			slp_clk = req_clk;
			slp_bw = req_bw;
		}

		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, 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;
}


static int update_context(uint32_t cl, bool active_only,
					unsigned int ctx_idx)
{
@@ -1352,8 +1281,8 @@ static int update_bw_adhoc(struct msm_bus_client_handle *cl, u64 ab, u64 ib)
	commit_data();
	cl->cur_act_ib = ib;
	cl->cur_act_ab = ab;
	cl->cur_slp_ib = slp_ib;
	cl->cur_slp_ab = slp_ab;
	cl->cur_dual_ib = slp_ib;
	cl->cur_dual_ab = slp_ab;

	if (log_transaction)
		getpath_debug(cl->mas, cl->first_hop, cl->active_only);
@@ -1378,18 +1307,18 @@ static int update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab,

	if ((cl->cur_act_ib == act_ib) &&
		(cl->cur_act_ab == act_ab) &&
		(cl->cur_slp_ib == slp_ib) &&
		(cl->cur_slp_ab == slp_ab)) {
		(cl->cur_dual_ib == slp_ib) &&
		(cl->cur_dual_ab == slp_ab)) {
		MSM_BUS_ERR("No change in vote");
		goto exit_change_context;
	}

	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_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);
	msm_bus_dbg_rec_transaction(cl, cl->cur_act_ab, cl->cur_dual_ib);
	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) {
		MSM_BUS_ERR("%s: Update path failed! %d active_only %d\n",
				__func__, ret, cl->active_only);
@@ -1398,8 +1327,8 @@ static int update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab,
	commit_data();
	cl->cur_act_ib = act_ib;
	cl->cur_act_ab = act_ab;
	cl->cur_slp_ib = slp_ib;
	cl->cur_slp_ab = slp_ab;
	cl->cur_dual_ib = slp_ib;
	cl->cur_dual_ab = slp_ab;
	trace_bus_update_request_end(cl->name);
exit_change_context:
	rt_mutex_unlock(&msm_bus_adhoc_lock);
@@ -1421,6 +1350,7 @@ static void unregister_adhoc(struct msm_bus_client_handle *cl)
				cl->first_hop, cl->active_only);
	commit_data();
	msm_bus_dbg_remove_client(cl);
	kfree(cl->name);
	kfree(cl);
exit_unregister_client:
	rt_mutex_unlock(&msm_bus_adhoc_lock);
+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -549,8 +549,8 @@ static int msm_bus_bimc_set_bw(struct msm_bus_node_device_type *dev,

	if (info && info->num_qports &&
		((info->qos_params.mode == BIMC_QOS_MODE_LIMITER))) {
		bw = msm_bus_div64(info->num_qports,
				dev->node_bw[ACTIVE_CTX].sum_ab);
		bw = msm_bus_div64(dev->node_bw[ACTIVE_CTX].sum_ab,
				info->num_qports);

		MSM_BUS_DBG("BIMC: Update mas_bw for ID: %d -> %llu\n",
				info->id, bw);
+3 −0
Original line number Diff line number Diff line
@@ -201,6 +201,7 @@ static struct msm_bus_node_device_type *msm_bus_floor_init_dev(
		sizeof(struct msm_bus_node_info_type), GFP_KERNEL);

	if (!node_info) {
		pr_err("%s:Bus node info alloc failed\n", __func__);
		devm_kfree(dev, bus_node);
		bus_node = ERR_PTR(-ENOMEM);
		goto exit_init_bus_dev;
@@ -462,6 +463,8 @@ static int msm_bus_floor_setup_floor_dev(
	cl_ptr->dev = kzalloc(sizeof(struct device), GFP_KERNEL);
	if (!cl_ptr->dev) {
		ret = -ENOMEM;
		pr_err("%s: Failed to create device bus %d", __func__,
			bus_node->node_info->id);
		goto err_setup_floor_dev;
	}

+12 −4
Original line number Diff line number Diff line
@@ -478,8 +478,10 @@ void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size,
		copy_size = new_size;

	ret = devm_kzalloc(dev, new_size, flags);
	if (!ret)
	if (!ret) {
		MSM_BUS_ERR("%s: Error Reallocating memory", __func__);
		goto exit_realloc_devmem;
	}

	memcpy(ret, p, copy_size);
	devm_kfree(dev, p);
@@ -716,6 +718,7 @@ static int msm_bus_fabric_init(struct device *dev,
	fabdev = devm_kzalloc(dev, sizeof(struct msm_bus_fab_device_type),
								GFP_KERNEL);
	if (!fabdev) {
		MSM_BUS_ERR("Fabric alloc failed\n");
		ret = -ENOMEM;
		goto exit_fabric_init;
	}
@@ -827,8 +830,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata,

	if (!bus_node || !pdata) {
		ret = -ENXIO;
		MSM_BUS_ERR("%s: NULL pointers for pdata or bus_node",
			__func__);
		MSM_BUS_ERR("%s: Invalid pointers pdata %p, bus_node %p",
			__func__, pdata, bus_node);
		goto exit_copy_node_info;
	}

@@ -968,6 +971,7 @@ static struct device *msm_bus_device_init(

	bus_node = kzalloc(sizeof(struct msm_bus_node_device_type), GFP_KERNEL);
	if (!bus_node) {
		MSM_BUS_ERR("%s:Bus node alloc failed\n", __func__);
		kfree(bus_dev);
		bus_dev = NULL;
		goto exit_device_init;
@@ -978,6 +982,7 @@ static struct device *msm_bus_device_init(
	node_info = devm_kzalloc(bus_dev,
			sizeof(struct msm_bus_node_info_type), GFP_KERNEL);
	if (!node_info) {
		MSM_BUS_ERR("%s:Bus node info alloc failed\n", __func__);
		devm_kfree(bus_dev, bus_node);
		kfree(bus_dev);
		bus_dev = NULL;
@@ -1210,6 +1215,9 @@ static int msm_bus_device_probe(struct platform_device *pdev)

	devm_kfree(&pdev->dev, pdata->info);
	devm_kfree(&pdev->dev, pdata);

	dev_info(&pdev->dev, "Bus scaling driver probe successful\n");

exit_device_probe:
	return ret;
}
@@ -1288,4 +1296,4 @@ int __init msm_bus_device_init_driver(void)
	}
	return platform_driver_register(&msm_bus_rules_driver);
}
subsys_initcall(msm_bus_device_init_driver);
fs_initcall(msm_bus_device_init_driver);
Loading