msm: msm_bus: Disallow 0 bw requests during early init
Any clients attempting to request 0 bandwidth during init time
is not immediately honored and flushed out at late init. This is
to prevent clients from turning off vital shared resources that
other clients may need but have not had a chance to probe and vote
yet.
Change-Id: I2e237a1d537720ad8e53c2cf38ab024273186a30
Signed-off-by: David Dai <daidavid1@codeaurora.org>
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
index 6993623..bf5a526 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
@@ -25,6 +25,7 @@
#define MAX_STR_CL 50
#define MSM_BUS_MAS_ALC 144
+#define MSM_BUS_RSC_APPS 8000
struct bus_search_type {
struct list_head link;
@@ -40,6 +41,7 @@
static LIST_HEAD(input_list);
static LIST_HEAD(apply_list);
static LIST_HEAD(commit_list);
+static LIST_HEAD(late_init_clist);
static LIST_HEAD(query_list);
DEFINE_RT_MUTEX(msm_bus_adhoc_lock);
@@ -652,32 +654,33 @@
int bcm_remove_handoff_req(struct device *dev, void *data)
{
- struct msm_bus_node_device_type *bcm_dev = NULL;
- int i;
- uint64_t max_ib = 0;
- uint64_t max_ab = 0;
+ struct msm_bus_node_device_type *bus_dev = NULL;
+ struct msm_bus_node_device_type *cur_bcm = NULL;
+ struct msm_bus_node_device_type *cur_rsc = NULL;
int ret = 0;
rt_mutex_lock(&msm_bus_adhoc_lock);
- bcm_dev = to_msm_bus_node(dev);
- if (!bcm_dev) {
- MSM_BUS_ERR("%s: Null device ptr", __func__);
- goto exit_bcm_remove_handoff_req;
- }
-
- if (!bcm_dev->node_info->is_bcm_dev)
+ bus_dev = to_msm_bus_node(dev);
+ if (bus_dev->node_info->is_bcm_dev ||
+ bus_dev->node_info->is_fab_dev ||
+ bus_dev->node_info->is_rsc_dev)
goto exit_bcm_remove_handoff_req;
- for (i = 0; i < bcm_dev->num_lnodes; i++) {
- max_ib = max(max_ib,
- bcm_dev->lnode_list[i].lnode_ib[0]);
- max_ab = max(max_ab,
- bcm_dev->lnode_list[i].lnode_ab[0]);
+ if (bus_dev->node_info->num_bcm_devs) {
+ cur_bcm = to_msm_bus_node(bus_dev->node_info->bcm_devs[0]);
+ if (cur_bcm->node_info->num_rsc_devs) {
+ cur_rsc =
+ to_msm_bus_node(cur_bcm->node_info->rsc_devs[0]);
+ if (cur_rsc->node_info->id != MSM_BUS_RSC_APPS)
+ goto exit_bcm_remove_handoff_req;
+ }
}
- bcm_dev->node_bw[0].max_ab = max_ab;
- bcm_dev->node_bw[0].max_ib = max_ib;
+ if (!bus_dev->dirty) {
+ list_add_tail(&bus_dev->link, &late_init_clist);
+ bus_dev->dirty = true;
+ }
exit_bcm_remove_handoff_req:
rt_mutex_unlock(&msm_bus_adhoc_lock);
@@ -807,6 +810,18 @@
INIT_LIST_HEAD(&commit_list);
}
+void commit_late_init_data(void)
+{
+ rt_mutex_lock(&msm_bus_adhoc_lock);
+
+ msm_bus_commit_data(&late_init_clist);
+ INIT_LIST_HEAD(&late_init_clist);
+
+ rt_mutex_unlock(&msm_bus_adhoc_lock);
+}
+
+
+
static void add_node_to_clist(struct msm_bus_node_device_type *node)
{
struct msm_bus_node_device_type *node_parent =
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
index fd80ab0..4167480 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
@@ -45,6 +45,7 @@
static struct list_head bcm_query_list_inorder[VCD_MAX_CNT];
static struct msm_bus_node_device_type *cur_rsc;
+static bool init_time = true;
struct bcm_db {
uint32_t unit_size;
@@ -484,7 +485,8 @@
if (cur_bcm->node_vec[DUAL_CTX].vec_a == 0 &&
cur_bcm->node_vec[ACTIVE_CTX].vec_a == 0 &&
cur_bcm->node_vec[DUAL_CTX].vec_b == 0 &&
- cur_bcm->node_vec[ACTIVE_CTX].vec_b == 0) {
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b == 0 &&
+ init_time == false) {
cur_bcm->dirty = false;
list_del_init(&cur_bcm->link);
}
@@ -553,8 +555,14 @@
cnt_sleep++;
cnt_wake++;
}
- if (!cur_bcm->updated)
- cnt_active++;
+ if (cur_bcm->updated ||
+ (cur_bcm->node_vec[DUAL_CTX].vec_a == 0 &&
+ cur_bcm->node_vec[ACTIVE_CTX].vec_a == 0 &&
+ cur_bcm->node_vec[DUAL_CTX].vec_b == 0 &&
+ cur_bcm->node_vec[ACTIVE_CTX].vec_b == 0 &&
+ init_time == true))
+ continue;
+ cnt_active++;
}
cnt_vcd++;
}
@@ -563,7 +571,8 @@
n_wake = kcalloc(cnt_vcd+1, sizeof(int), GFP_KERNEL);
n_sleep = kcalloc(cnt_vcd+1, sizeof(int), GFP_KERNEL);
- cmdlist_active = kcalloc(cnt_active, sizeof(struct tcs_cmd),
+ if (cnt_active)
+ cmdlist_active = kcalloc(cnt_active, sizeof(struct tcs_cmd),
GFP_KERNEL);
if (cnt_sleep && cnt_wake) {
cmdlist_wake = kcalloc(cnt_wake, sizeof(struct tcs_cmd),
@@ -1285,6 +1294,7 @@
bus_node->node_info = node_info;
bus_node->ap_owned = pdata->ap_owned;
+ bus_node->dirty = false;
bus_dev->of_node = pdata->of_node;
if (msm_bus_copy_node_info(pdata, bus_dev) < 0) {
@@ -1649,9 +1659,11 @@
int rc;
MSM_BUS_ERR("msm_bus_late_init: Remove handoff bw requests\n");
+ init_time = false;
rc = bus_for_each_dev(&msm_bus_type, NULL, NULL,
bcm_remove_handoff_req);
+ commit_late_init_data();
return rc;
}
subsys_initcall(msm_bus_device_init_driver);
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h b/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h
index 10bf794..fad7afa 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h
+++ b/drivers/soc/qcom/msm_bus/msm_bus_rpmh.h
@@ -201,6 +201,7 @@
int throttle_en, uint64_t lim_bw);
int msm_bus_commit_data(struct list_head *clist);
int bcm_remove_handoff_req(struct device *dev, void *data);
+void commit_late_init_data(void);
int msm_bus_query_gen(struct list_head *qlist,
struct msm_bus_tcs_usecase *tcs_usecase);
void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size,