diff options
Diffstat (limited to 'packages/linux/linux-omap2-git/beagleboard/01-postrate-notifier.eml')
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/01-postrate-notifier.eml | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/packages/linux/linux-omap2-git/beagleboard/01-postrate-notifier.eml b/packages/linux/linux-omap2-git/beagleboard/01-postrate-notifier.eml deleted file mode 100644 index 8e72afeb3f..0000000000 --- a/packages/linux/linux-omap2-git/beagleboard/01-postrate-notifier.eml +++ /dev/null @@ -1,392 +0,0 @@ -Add the infrastructure necessary to support clock post-rate-change notifiers -in the OMAP clock framework. This includes: - -- adding the clk_notify_post_rate_chg() function, which will trigger a - notifier call chain when a clock rate is changed (but which currently - does nothing); and - -- adding calls to clk_notify_post_rate_chg() everywhere clk->rate is - assigned (mostly *_recalc() functions). - -This patch has no functional effect by itself; the actual notifier -implementation follows in a separate patch. - -One item to note is that the post-rate-change notifier is called even -if the new clock rate is identical to the old rate. This is because -the process of changing the rate may have temporarily disabled or -glitched the clock or one of its parents, and some devices may be -sensitive to such changes. - -Signed-off-by: Paul Walmsley <paul@pwsan.com> ---- - - arch/arm/mach-omap2/clock.c | 37 +++++++++++++++++++++++++++------ - arch/arm/mach-omap2/clock24xx.c | 42 +++++++++++++++++++++++++++++++++++-- - arch/arm/mach-omap2/clock34xx.c | 10 +++++++++ - arch/arm/plat-omap/clock.c | 32 ++++++++++++++++++++++++++++ - include/asm-arm/arch-omap/clock.h | 21 +++++++++++++++++++ - 5 files changed, 134 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c -index ed15868..bd3c1f8 100644 ---- a/arch/arm/mach-omap2/clock.c -+++ b/arch/arm/mach-omap2/clock.c -@@ -165,10 +165,15 @@ u32 omap2_get_dpll_rate(struct clk *clk) - */ - void omap2_fixed_divisor_recalc(struct clk *clk) - { -+ unsigned long orig_rate; -+ - WARN_ON(!clk->fixed_div); - -+ orig_rate = clk->rate; - clk->rate = clk->parent->rate / clk->fixed_div; - -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - if (clk->flags & RATE_PROPAGATES) - propagate_rate(clk); - } -@@ -376,6 +381,7 @@ int omap2_clk_enable(struct clk *clk) - void omap2_clksel_recalc(struct clk *clk) - { - u32 div = 0; -+ unsigned long orig_rate; - - pr_debug("clock: recalc'ing clksel clk %s\n", clk->name); - -@@ -385,10 +391,13 @@ void omap2_clksel_recalc(struct clk *clk) - - if (clk->rate == (clk->parent->rate / div)) - return; -+ orig_rate = clk->rate; - clk->rate = clk->parent->rate / div; - - pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div); - -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - if (clk->flags & RATE_PROPAGATES) - propagate_rate(clk); - } -@@ -662,6 +671,8 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) - wmb(); - } - -+ /* post-rate-change notifier will be called by omap2_clk_set_rate() */ -+ - return 0; - } - -@@ -670,20 +681,30 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) - int omap2_clk_set_rate(struct clk *clk, unsigned long rate) - { - int ret = -EINVAL; -- -- pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate); -+ unsigned long orig_rate; - - /* CONFIG_PARTICIPANT clocks are changed only in sets via the - rate table mechanism, driven by mpu_speed */ - if (clk->flags & CONFIG_PARTICIPANT) - return -EINVAL; - -+ if (!clk->set_rate) -+ return -EINVAL; -+ -+ orig_rate = clk->rate; -+ -+ pr_debug("clock: set_rate for clock %s from %ld Hz to %ld Hz\n", -+ clk->name, orig_rate, rate); -+ - /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ -- if (clk->set_rate) -- ret = clk->set_rate(clk, rate); -+ ret = clk->set_rate(clk, rate); - -- if (ret == 0 && (clk->flags & RATE_PROPAGATES)) -- propagate_rate(clk); -+ if (ret == 0) { -+ clk_notify_post_rate_chg(clk, orig_rate, rate); -+ -+ if (clk->flags & RATE_PROPAGATES) -+ propagate_rate(clk); -+ } - - return ret; - } -@@ -732,6 +753,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) - { - void __iomem *src_addr; - u32 field_val, field_mask, reg_val, parent_div; -+ unsigned long orig_rate; - - if (clk->flags & CONFIG_PARTICIPANT) - return -EINVAL; -@@ -765,11 +787,14 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) - clk->parent = new_parent; - - /* CLKSEL clocks follow their parents' rates, divided by a divisor */ -+ orig_rate = clk->rate; - clk->rate = new_parent->rate; - - if (parent_div > 0) - clk->rate /= parent_div; - -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - pr_debug("clock: set parent of %s to %s (new rate %ld)\n", - clk->name, clk->parent->name, clk->rate); - -diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c -index 54cc6e1..e001549 100644 ---- a/arch/arm/mach-omap2/clock24xx.c -+++ b/arch/arm/mach-omap2/clock24xx.c -@@ -172,11 +172,22 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate) - - static void omap2_dpllcore_recalc(struct clk *clk) - { -+ unsigned long orig_rate; -+ -+ orig_rate = clk->rate; - clk->rate = omap2_get_dpll_rate_24xx(clk); - -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - propagate_rate(clk); - } - -+/* -+ * XXX REVISIT: This code needs to keep track of the underlying struct -+ * clocks that it is changing, so it can call post-rate-change notifiers -+ * on them. This function probably should be rewritten to use the clock -+ * fw. -+ */ - static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) - { - u32 cur_rate, low, mult, div, valid_rate, done_rate; -@@ -259,7 +270,14 @@ dpll_exit: - */ - static void omap2_table_mpu_recalc(struct clk *clk) - { -+ unsigned long orig_rate; -+ -+ orig_rate = clk->rate; - clk->rate = curr_prcm_set->mpu_speed; -+ -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ -+ /* No rate propagation since table clocks have no children */ - } - - /* -@@ -294,7 +312,14 @@ static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) - return highest_rate; - } - --/* Sets basic clocks based on the specified rate */ -+/* -+ * Sets basic clocks based on the specified rate -+ * -+ * XXX REVISIT: This code needs to keep track of the underlying struct -+ * clocks that it is changing, so it can call post-rate-change notifiers -+ * on them. This function probably should be rewritten to use the clock -+ * fw. -+ */ - static int omap2_select_table_rate(struct clk *clk, unsigned long rate) - { - u32 cur_rate, done_rate, bypass = 0, tmp; -@@ -353,7 +378,8 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate) - cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL); - - /* Major subsystem dividers */ -- tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK; -+ tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & -+ OMAP24XX_CLKSEL_DSS2_MASK; - cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, - CM_CLKSEL1); - -@@ -460,13 +486,25 @@ static u32 omap2_get_sysclkdiv(void) - - static void omap2_osc_clk_recalc(struct clk *clk) - { -+ unsigned long orig_rate; -+ -+ orig_rate = clk->rate; - clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv(); -+ -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - propagate_rate(clk); - } - - static void omap2_sys_clk_recalc(struct clk *clk) - { -+ unsigned long orig_rate; -+ -+ orig_rate = clk->rate; - clk->rate = clk->parent->rate / omap2_get_sysclkdiv(); -+ -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - propagate_rate(clk); - } - -diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c -index 408b51a..7b89b61 100644 ---- a/arch/arm/mach-omap2/clock34xx.c -+++ b/arch/arm/mach-omap2/clock34xx.c -@@ -53,8 +53,13 @@ - */ - static void omap3_dpll_recalc(struct clk *clk) - { -+ unsigned long orig_rate; -+ -+ orig_rate = clk->rate; - clk->rate = omap2_get_dpll_rate(clk); - -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - propagate_rate(clk); - } - -@@ -500,6 +505,7 @@ static void omap3_clkoutx2_recalc(struct clk *clk) - const struct dpll_data *dd; - u32 v; - struct clk *pclk; -+ unsigned long orig_rate; - - /* Walk up the parents of clk, looking for a DPLL */ - pclk = clk->parent; -@@ -513,6 +519,8 @@ static void omap3_clkoutx2_recalc(struct clk *clk) - - WARN_ON(!dd->control_reg || !dd->enable_mask); - -+ orig_rate = clk->rate; -+ - v = __raw_readl(dd->control_reg) & dd->enable_mask; - v >>= __ffs(dd->enable_mask); - if (v != DPLL_LOCKED) -@@ -520,6 +528,8 @@ static void omap3_clkoutx2_recalc(struct clk *clk) - else - clk->rate = clk->parent->rate * 2; - -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - if (clk->flags & RATE_PROPAGATES) - propagate_rate(clk); - } -diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c -index c2e741d..421d076 100644 ---- a/arch/arm/plat-omap/clock.c -+++ b/arch/arm/plat-omap/clock.c -@@ -254,10 +254,16 @@ __setup("mpurate=", omap_clk_setup); - /* Used for clocks that always have same value as the parent clock */ - void followparent_recalc(struct clk *clk) - { -+ unsigned long orig_rate; -+ - if (clk == NULL || IS_ERR(clk)) - return; - -+ orig_rate = clk->rate; - clk->rate = clk->parent->rate; -+ -+ clk_notify_post_rate_chg(clk, orig_rate, clk->rate); -+ - if (unlikely(clk->flags & RATE_PROPAGATES)) - propagate_rate(clk); - } -@@ -373,6 +379,32 @@ void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) - EXPORT_SYMBOL(clk_init_cpufreq_table); - #endif - -+/** -+ * clk_notify_post_rate_chg - call post-clk-rate-change notifier chain -+ * @clk: struct clk * that is changing rate -+ * @old_rate: old rate -+ * @new_rate: new rate -+ * -+ * Triggers a notifier call chain on the post-clk-rate-change notifier -+ * for clock 'clk'. Passes a pointer to the struct clk and the -+ * previous and current rates to the notifier callback. Intended to be -+ * called by internal clock code only. No return value. -+ */ -+void clk_notify_post_rate_chg(struct clk *clk, unsigned long old_rate, -+ unsigned long new_rate) -+{ -+ struct clk_notifier *cn; -+ struct clk_notifier_data cnd; -+ -+ cnd.clk = clk; -+ cnd.old_rate = old_rate; -+ cnd.new_rate = new_rate; -+ -+ /* XXX Call notifier here */ -+ -+} -+ -+ - /*-------------------------------------------------------------------------*/ - - #ifdef CONFIG_OMAP_RESET_CLOCKS -diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h -index bfaf7b6..e3c9aeb 100644 ---- a/include/asm-arm/arch-omap/clock.h -+++ b/include/asm-arm/arch-omap/clock.h -@@ -10,6 +10,8 @@ - * published by the Free Software Foundation. - */ - -+#include <linux/notifier.h> -+ - #ifndef __ARCH_ARM_OMAP_CLOCK_H - #define __ARCH_ARM_OMAP_CLOCK_H - -@@ -58,6 +60,19 @@ struct dpll_data { - - #endif - -+struct clk_notifier { -+ struct clk *clk; -+ struct atomic_notifier_head notifier_head; -+ struct list_head node; -+}; -+ -+struct clk_notifier_data { -+ struct clk *clk; -+ unsigned long old_rate; -+ unsigned long new_rate; -+}; -+ -+ - struct clk { - struct list_head node; - struct module *owner; -@@ -121,6 +136,10 @@ extern void clk_allow_idle(struct clk *clk); - extern void clk_deny_idle(struct clk *clk); - extern int clk_get_usecount(struct clk *clk); - extern void clk_enable_init_clocks(void); -+extern int clk_notifier_register(struct clk *clk, struct notifier_block *nb); -+extern int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); -+extern void clk_notify_post_rate_chg(struct clk *clk, unsigned long old_rate, -+ unsigned long new_rate); - #ifdef CONFIG_CPU_FREQ - extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); - #endif -@@ -161,6 +180,8 @@ extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); - - #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) - -+/* Clk rate change notifier callback type */ -+#define CLK_POST_RATE_CHANGE 1 - - /* CM_CLKSEL2_PLL.CORE_CLK_SRC options (24XX) */ - #define CORE_CLK_SRC_32K 0 - - --- -To unsubscribe from this list: send the line "unsubscribe linux-omap" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - |