Skip to content

Commit

Permalink
sh: SH7722 clock framework support.
Browse files Browse the repository at this point in the history
This adds support for the SH7722 (MobileR) to the clock framework.

Signed-off-by: dmitry pervushin <[email protected]>
Signed-off-by: Paul Mundt <[email protected]>
  • Loading branch information
dmitry pervushin authored and Paul Mundt committed May 7, 2007
1 parent 34a780a commit 1929cb3
Showing 7 changed files with 694 additions and 7 deletions.
32 changes: 32 additions & 0 deletions Documentation/sh/clk.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Clock framework on SuperH architecture

The framework on SH extends existing API by the function clk_set_rate_ex,
which prototype is as follows:

clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id)

The algo_id parameter is used to specify algorithm used to recalculate clocks,
adjanced to clock, specified as first argument. It is assumed that algo_id==0
means no changes to adjanced clock

Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method,
if it is present in ops structure. The method should set the clock rate and adjust
all needed clocks according to the passed algo_id.
Exact values for algo_id are machine-dependend. For the sh7722, the following
values are defined:

NO_CHANGE = 0,
IUS_N1_N1, /* I:U = N:1, U:Sh = N:1 */
IUS_322, /* I:U:Sh = 3:2:2 */
IUS_522, /* I:U:Sh = 5:2:2 */
IUS_N11, /* I:U:Sh = N:1:1 */
SB_N1, /* Sh:B = N:1 */
SB3_N1, /* Sh:B3 = N:1 */
SB3_32, /* Sh:B3 = 3:2 */
SB3_43, /* Sh:B3 = 4:3 */
SB3_54, /* Sh:B3 = 5:4 */
BP_N1, /* B:P = N:1 */
IP_N1 /* I:P = N:1 */

Each of these constants means relation between clocks that can be set via the FRQCR
register
28 changes: 24 additions & 4 deletions arch/sh/kernel/cpu/clock.c
Original file line number Diff line number Diff line change
@@ -98,13 +98,14 @@ int __clk_enable(struct clk *clk)
if (clk->ops && clk->ops->init)
clk->ops->init(clk);

kref_get(&clk->kref);

if (clk->flags & CLK_ALWAYS_ENABLED)
return 0;

if (likely(clk->ops && clk->ops->enable))
clk->ops->enable(clk);

kref_get(&clk->kref);
return 0;
}

@@ -127,10 +128,15 @@ static void clk_kref_release(struct kref *kref)

void __clk_disable(struct clk *clk)
{
int count = kref_put(&clk->kref, clk_kref_release);

if (clk->flags & CLK_ALWAYS_ENABLED)
return;

kref_put(&clk->kref, clk_kref_release);
if (!count) { /* count reaches zero, disable the clock */
if (likely(clk->ops && clk->ops->disable))
clk->ops->disable(clk);
}
}

void clk_disable(struct clk *clk)
@@ -151,6 +157,15 @@ int clk_register(struct clk *clk)

mutex_unlock(&clock_list_sem);

if (clk->flags & CLK_ALWAYS_ENABLED) {
pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name);
if (clk->ops && clk->ops->init)
clk->ops->init(clk);
if (clk->ops && clk->ops->enable)
clk->ops->enable(clk);
pr_debug( "Enabled.");
}

return 0;
}

@@ -167,14 +182,19 @@ inline unsigned long clk_get_rate(struct clk *clk)
}

int clk_set_rate(struct clk *clk, unsigned long rate)
{
return clk_set_rate_ex(clk, rate, 0);
}

int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
{
int ret = -EOPNOTSUPP;

if (likely(clk->ops && clk->ops->set_rate)) {
unsigned long flags;

spin_lock_irqsave(&clock_lock, flags);
ret = clk->ops->set_rate(clk, rate);
ret = clk->ops->set_rate(clk, rate, algo_id);
spin_unlock_irqrestore(&clock_lock, flags);
}

@@ -256,7 +276,6 @@ int __init clk_init(void)

arch_init_clk_ops(&clk->ops, i);
ret |= clk_register(clk);
clk_enable(clk);
}

/* Kick the child clocks.. */
@@ -298,3 +317,4 @@ EXPORT_SYMBOL_GPL(__clk_disable);
EXPORT_SYMBOL_GPL(clk_get_rate);
EXPORT_SYMBOL_GPL(clk_set_rate);
EXPORT_SYMBOL_GPL(clk_recalc_rate);
EXPORT_SYMBOL_GPL(clk_set_rate_ex);
3 changes: 2 additions & 1 deletion arch/sh/kernel/cpu/sh4/clock-sh4-202.c
Original file line number Diff line number Diff line change
@@ -82,7 +82,8 @@ static void shoc_clk_init(struct clk *clk)
for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
int divisor = frqcr3_divisors[i];

if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
if (clk->ops->set_rate(clk, clk->parent->rate /
divisor, 0) == 0)
break;
}

2 changes: 1 addition & 1 deletion arch/sh/kernel/cpu/sh4a/Makefile
Original file line number Diff line number Diff line change
@@ -16,6 +16,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o

obj-y += $(clock-y)
Loading

0 comments on commit 1929cb3

Please sign in to comment.