Merge "clk: Check for failure at clk_change_rate" into msm-4.8
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 1cff20e..405c2ee 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1466,7 +1466,7 @@
* walk down a subtree and set the new rates notifying the rate
* change on the way
*/
-static void clk_change_rate(struct clk_core *core)
+static int clk_change_rate(struct clk_core *core)
{
struct clk_core *child;
struct hlist_node *tmp;
@@ -1475,6 +1475,7 @@
bool skip_set_rate = false;
struct clk_core *old_parent;
struct clk_core *parent = NULL;
+ int rc = 0;
old_rate = core->rate;
@@ -1517,8 +1518,13 @@
trace_clk_set_rate(core, core->new_rate);
- if (!skip_set_rate && core->ops->set_rate)
- core->ops->set_rate(core->hw, core->new_rate, best_parent_rate);
+ if (!skip_set_rate && core->ops->set_rate) {
+ rc = core->ops->set_rate(core->hw, core->new_rate,
+ best_parent_rate);
+ if (rc)
+ goto out;
+
+ }
trace_clk_set_rate_complete(core, core->new_rate);
@@ -1550,12 +1556,20 @@
/* Skip children who will be reparented to another clock */
if (child->new_parent && child->new_parent != core)
continue;
- clk_change_rate(child);
+ rc = clk_change_rate(child);
+ if (rc)
+ return rc;
}
/* handle the new child who might not be in core->children yet */
if (core->new_child)
- clk_change_rate(core->new_child);
+ rc = clk_change_rate(core->new_child);
+
+ return rc;
+out:
+ trace_clk_set_rate_complete(core, core->new_rate);
+
+ return rc;
}
static int clk_core_set_rate_nolock(struct clk_core *core,
@@ -1563,6 +1577,7 @@
{
struct clk_core *top, *fail_clk;
unsigned long rate = req_rate;
+ int ret = 0;
if (!core)
return 0;
@@ -1582,18 +1597,24 @@
/* notify that we are about to change rates */
fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
if (fail_clk) {
- pr_debug("%s: failed to set %s rate\n", __func__,
- fail_clk->name);
+ pr_debug("%s: failed to set %s clock to run at %lu\n", __func__,
+ fail_clk->name, req_rate);
clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
return -EBUSY;
}
/* change the rates */
- clk_change_rate(top);
+ ret = clk_change_rate(top);
+ if (ret) {
+ pr_err("%s: failed to set %s clock to run at %lu\n", __func__,
+ top->name, req_rate);
+ clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
+ return ret;
+ }
core->req_rate = req_rate;
- return 0;
+ return ret;
}
/**