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

Commit c36429f9 authored by Girish Mahadevan's avatar Girish Mahadevan Committed by Gerrit - the friendly Code Review server
Browse files

msm: msm_bus: Mark certain rule transitions as post clock commit



When evaluating non-callback rules, if we're moving to a less
restrictive rule then mark these as post clock commit. Meaning
instruct the bus driver to apply the rules after committing the
clock rates.
This is essential in some cases where AP flooding control is
essential to protect other shared bus master's timelines. Without
this change, it is possible that AP flooding control is removed before
the clk transitions go through leaving a small window during which AP
bus flooding can cause issues for timelines of other bus masters.

Change-Id: I8d9d0385d16dd27b9c703860253abef35e9e213e
Signed-off-by: default avatarGirish Mahadevan <girishm@codeaurora.org>
parent 819f45d3
Loading
Loading
Loading
Loading
+33 −14
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2015, 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
@@ -38,7 +38,7 @@ struct rule_node_info {
	int id;
	void *data;
	struct raw_notifier_head rule_notify_list;
	int cur_rule;
	struct rules_def *cur_rule;
	int num_rules;
	struct list_head node_rules;
	struct list_head link;
@@ -48,6 +48,8 @@ struct rule_node_info {
DEFINE_MUTEX(msm_bus_rules_lock);
static LIST_HEAD(node_list);
static struct rule_node_info *get_node(u32 id, void *data);
static int node_rules_compare(void *priv, struct list_head *a,
					struct list_head *b);

#define LE(op1, op2)	(op1 <= op2)
#define LT(op1, op2)	(op1 < op2)
@@ -96,7 +98,7 @@ static struct rule_node_info *gen_node(u32 id, void *data)
		}

		node_match->id = id;
		node_match->cur_rule = -1;
		node_match->cur_rule = NULL;
		node_match->num_rules = 0;
		node_match->data = data;
		list_add_tail(&node_match->link, &node_list);
@@ -210,7 +212,9 @@ static void match_rule(struct rule_update_path_info *inp_node,
		for (i = 0; i < rule->num_src; i++) {
			if (rule->src_info[i].id == inp_node->id) {
				if (check_rule(rule, inp_node)) {
					trace_bus_rules_matches(node->cur_rule,
					trace_bus_rules_matches(
					(node->cur_rule ?
						node->cur_rule->rule_id : -1),
					inp_node->id, inp_node->ab,
					inp_node->ib, inp_node->clk);
					if (rule->state ==
@@ -232,12 +236,14 @@ static void apply_rule(struct rule_node_info *node,
			struct list_head *output_list)
{
	struct rules_def *rule;
	struct rules_def *last_rule;

	node->cur_rule = -1;
	last_rule = node->cur_rule;
	node->cur_rule = NULL;
	list_for_each_entry(rule, &node->node_rules, link) {
		if ((rule->state == RULE_STATE_APPLIED) &&
						(node->cur_rule == -1))
			node->cur_rule = rule->rule_id;
						!node->cur_rule)
			node->cur_rule = rule;

		if (node->id == NB_ID) {
			if (rule->state_change) {
@@ -247,11 +253,22 @@ static void apply_rule(struct rule_node_info *node,
			}
		} else {
			if ((rule->state == RULE_STATE_APPLIED) &&
				(node->cur_rule == rule->rule_id)) {
			     (node->cur_rule &&
				(node->cur_rule->rule_id == rule->rule_id))) {
				node->apply.id = rule->rule_ops.dst_node[0];
				node->apply.throttle = rule->rule_ops.mode;
				node->apply.lim_bw = rule->rule_ops.dst_bw;
				list_add_tail(&node->apply.link, output_list);
				node->apply.after_clk_commit = false;
				if (last_rule != node->cur_rule)
					list_add_tail(&node->apply.link,
								output_list);
				if (last_rule) {
					if (node_rules_compare(NULL,
						&last_rule->link,
						&node->cur_rule->link) == -1)
						node->apply.after_clk_commit =
									true;
				}
			}
			rule->state_change = false;
		}
@@ -368,7 +385,8 @@ static void print_rules(struct rule_node_info *node_it)
	}

	pr_info("\n Now printing rules for Node %d  cur rule %d\n",
						node_it->id, node_it->cur_rule);
			node_it->id,
			(node_it->cur_rule ? node_it->cur_rule->rule_id : -1));
	list_for_each_entry(node_rule, &node_it->node_rules, link) {
		pr_info("\n num Rules %d  rule Id %d\n",
				node_it->num_rules, node_rule->rule_id);
@@ -406,7 +424,8 @@ void print_rules_buf(char *buf, int max_buf)
	list_for_each_entry(node_it, &node_list, link) {
		cnt += scnprintf(buf + cnt, max_buf - cnt,
			"\n Now printing rules for Node %d cur_rule %d\n",
					node_it->id, node_it->cur_rule);
			node_it->id,
			(node_it->cur_rule ? node_it->cur_rule->rule_id : -1));
		list_for_each_entry(node_rule, &node_it->node_rules, link) {
			cnt += scnprintf(buf + cnt, max_buf - cnt,
				"\nNum Rules:%d ruleId %d STATE:%d change:%d\n",