else if (core->parent)
                best_parent_rate = core->parent->rate;
 
+       if (core->flags & CLK_SET_RATE_UNGATE) {
+               unsigned long flags;
+
+               clk_core_prepare(core);
+               flags = clk_enable_lock();
+               clk_core_enable(core);
+               clk_enable_unlock(flags);
+       }
+
        if (core->new_parent && core->new_parent != core->parent) {
                old_parent = __clk_set_parent_before(core, core->new_parent);
                trace_clk_set_parent(core, core->new_parent);
 
        core->rate = clk_recalc(core, best_parent_rate);
 
+       if (core->flags & CLK_SET_RATE_UNGATE) {
+               unsigned long flags;
+
+               flags = clk_enable_lock();
+               clk_core_disable(core);
+               clk_enable_unlock(flags);
+               clk_core_unprepare(core);
+       }
+
        if (core->notifier_count && old_rate != core->rate)
                __clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
 
 
 #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
 #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
 #define CLK_RECALC_NEW_RATES   BIT(9) /* recalc rates after notifications */
+#define CLK_SET_RATE_UNGATE    BIT(10) /* clock needs to run to set rate */
 
 struct clk;
 struct clk_hw;