clk: Add parent change notifications

Added parent change notifications to be used when drivers behavior
depends on physical nature of the parent, not just clock rate it
supplies (e.g., selection of Tegra DFLL as CPU clock source changes
mechanism of voltage control even if the clock rate stays the same
as on PLL).

Bug 200269751

Change-Id: I617c94927ef437caf240efd91497b49ad6f5c39d
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1573111
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
Reviewed-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Tested-by: Peter De Schrijver <pdeschrijver@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Timo Alho <talho@nvidia.com>
This commit is contained in:
Alex Frid
2017-02-07 14:04:44 -08:00
committed by Thomas Makin
parent 5d5fa5fea6
commit c9e1fe2463
2 changed files with 27 additions and 2 deletions

View File

@@ -2959,6 +2959,7 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
int ret = 0;
int p_index = 0;
unsigned long p_rate = 0;
unsigned long old_p_rate = 0;
lockdep_assert_held(&prepare_lock);
@@ -3001,13 +3002,23 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
if (ret & NOTIFY_STOP_MASK)
goto runtime_put;
/* do the re-parent */
ret = __clk_set_parent(core, parent, p_index);
/* propagate PRE_PARENT_CHANGE notifications */
if (core->parent)
old_p_rate = core->parent->rate;
ret = __clk_notify(core, PRE_PARENT_CHANGE, old_p_rate, p_rate);
/* do the re-parent if no objections */
if (!(ret & NOTIFY_STOP_MASK))
ret = __clk_set_parent(core, parent, p_index);
/* propagate rate an accuracy recalculation accordingly */
if (ret) {
__clk_notify(core, ABORT_PARENT_CHANGE, old_p_rate, p_rate);
__clk_recalc_rates(core, true, ABORT_RATE_CHANGE);
} else {
__clk_notify(core, POST_PARENT_CHANGE, old_p_rate, p_rate);
__clk_recalc_rates(core, true, POST_RATE_CHANGE);
__clk_recalc_accuracies(core);
}

View File

@@ -42,12 +42,26 @@ struct of_phandle_args;
* POST_SUBTREE_UPDATE - called after rate change is propagated down to
* sub-tree rooted in clk. Callbacks must always return NOTIFY_DONE
* or NOTIFY_OK.
*
* PRE_PARENT_CHANGE - called immediately before the clk parent is changed,
* to indicate that the parent change will proceed. Callbacks may either
* return NOTIFY_DONE, NOTIFY_OK, NOTIFY_STOP or NOTIFY_BAD.
*
* ABORT_PARENT_CHANGE: called if the parent change failed for some reason
* after PRE_PARENT_CHANGE. Callbacks must always return NOTIFY_DONE or
* NOTIFY_OK.
*
* POST_PARENT_CHANGE - called after the clk parent change has successfully
* completed. Callbacks must always return NOTIFY_DONE or NOTIFY_OK.
*/
#define PRE_RATE_CHANGE BIT(0)
#define POST_RATE_CHANGE BIT(1)
#define ABORT_RATE_CHANGE BIT(2)
#define PRE_SUBTREE_CHANGE BIT(3)
#define POST_SUBTREE_CHANGE BIT(4)
#define PRE_PARENT_CHANGE BIT(5)
#define POST_PARENT_CHANGE BIT(6)
#define ABORT_PARENT_CHANGE BIT(7)
/**
* struct clk_notifier - associate a clk with a notifier