···11+Clock framework on SuperH architecture22+33+The framework on SH extends existing API by the function clk_set_rate_ex,44+which prototype is as follows:55+66+ clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id)77+88+The algo_id parameter is used to specify algorithm used to recalculate clocks,99+adjanced to clock, specified as first argument. It is assumed that algo_id==01010+means no changes to adjanced clock1111+1212+Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method,1313+if it is present in ops structure. The method should set the clock rate and adjust1414+all needed clocks according to the passed algo_id.1515+Exact values for algo_id are machine-dependend. For the sh7722, the following1616+values are defined:1717+1818+ NO_CHANGE = 0,1919+ IUS_N1_N1, /* I:U = N:1, U:Sh = N:1 */2020+ IUS_322, /* I:U:Sh = 3:2:2 */2121+ IUS_522, /* I:U:Sh = 5:2:2 */2222+ IUS_N11, /* I:U:Sh = N:1:1 */2323+ SB_N1, /* Sh:B = N:1 */2424+ SB3_N1, /* Sh:B3 = N:1 */2525+ SB3_32, /* Sh:B3 = 3:2 */2626+ SB3_43, /* Sh:B3 = 4:3 */2727+ SB3_54, /* Sh:B3 = 5:4 */2828+ BP_N1, /* B:P = N:1 */2929+ IP_N1 /* I:P = N:1 */3030+3131+Each of these constants means relation between clocks that can be set via the FRQCR3232+register
+24-4
arch/sh/kernel/cpu/clock.c
···9898 if (clk->ops && clk->ops->init)9999 clk->ops->init(clk);100100101101+ kref_get(&clk->kref);102102+101103 if (clk->flags & CLK_ALWAYS_ENABLED)102104 return 0;103105104106 if (likely(clk->ops && clk->ops->enable))105107 clk->ops->enable(clk);106108107107- kref_get(&clk->kref);108109 return 0;109110}110111···128127129128void __clk_disable(struct clk *clk)130129{130130+ int count = kref_put(&clk->kref, clk_kref_release);131131+131132 if (clk->flags & CLK_ALWAYS_ENABLED)132133 return;133134134134- kref_put(&clk->kref, clk_kref_release);135135+ if (!count) { /* count reaches zero, disable the clock */136136+ if (likely(clk->ops && clk->ops->disable))137137+ clk->ops->disable(clk);138138+ }135139}136140137141void clk_disable(struct clk *clk)···157151158152 mutex_unlock(&clock_list_sem);159153154154+ if (clk->flags & CLK_ALWAYS_ENABLED) {155155+ pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name);156156+ if (clk->ops && clk->ops->init)157157+ clk->ops->init(clk);158158+ if (clk->ops && clk->ops->enable)159159+ clk->ops->enable(clk);160160+ pr_debug( "Enabled.");161161+ }162162+160163 return 0;161164}162165···183168184169int clk_set_rate(struct clk *clk, unsigned long rate)185170{171171+ return clk_set_rate_ex(clk, rate, 0);172172+}173173+174174+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)175175+{186176 int ret = -EOPNOTSUPP;187177188178 if (likely(clk->ops && clk->ops->set_rate)) {189179 unsigned long flags;190180191181 spin_lock_irqsave(&clock_lock, flags);192192- ret = clk->ops->set_rate(clk, rate);182182+ ret = clk->ops->set_rate(clk, rate, algo_id);193183 spin_unlock_irqrestore(&clock_lock, flags);194184 }195185···276256277257 arch_init_clk_ops(&clk->ops, i);278258 ret |= clk_register(clk);279279- clk_enable(clk);280259 }281260282261 /* Kick the child clocks.. */···317298EXPORT_SYMBOL_GPL(clk_get_rate);318299EXPORT_SYMBOL_GPL(clk_set_rate);319300EXPORT_SYMBOL_GPL(clk_recalc_rate);301301+EXPORT_SYMBOL_GPL(clk_set_rate_ex);
+2-1
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
···8282 for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {8383 int divisor = frqcr3_divisors[i];84848585- if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)8585+ if (clk->ops->set_rate(clk, clk->parent->rate /8686+ divisor, 0) == 0)8687 break;8788 }8889