From 942219bb95734329c858587806e49895bae29208 Mon Sep 17 00:00:00 2001
From: Francesco Virlinzi <francesco.virlinzi@st.com>
Date: Fri, 13 Mar 2009 09:32:45 +0100
Subject: [PATCH] sh: clkfwk: Changed the init field to return a value
This patch changes the clk_ops.init function pointer
to return a value.
Moreover it change the clk_register function to call
always the clk_ops.init function to initilize the clock
if there is an error the clock _isn't_ registered.
Signed-off-by: Francesco Virlinzi <francesco.virlinzi@st.com>
---
arch/sh/include/asm/clock.h | 2 +-
arch/sh/kernel/cpu/clock.c | 18 +++++-------------
arch/sh/kernel/cpu/sh2/clock-sh7619.c | 3 ++-
arch/sh/kernel/cpu/sh2a/clock-sh7201.c | 3 ++-
arch/sh/kernel/cpu/sh2a/clock-sh7203.c | 3 ++-
arch/sh/kernel/cpu/sh2a/clock-sh7206.c | 3 ++-
arch/sh/kernel/cpu/sh3/clock-sh3.c | 3 ++-
arch/sh/kernel/cpu/sh3/clock-sh7705.c | 3 ++-
arch/sh/kernel/cpu/sh3/clock-sh7706.c | 3 ++-
arch/sh/kernel/cpu/sh3/clock-sh7709.c | 3 ++-
arch/sh/kernel/cpu/sh3/clock-sh7712.c | 3 ++-
arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 3 ++-
arch/sh/kernel/cpu/sh4/clock-sh4.c | 3 ++-
arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 3 ++-
arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 3 ++-
arch/sh/kernel/cpu/sh4a/clock-sh7770.c | 3 ++-
arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 3 ++-
arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 3 ++-
arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 3 ++-
arch/sh/kernel/cpu/sh4a/clock-shx3.c | 3 ++-
arch/sh/kernel/cpu/sh5/clock-sh5.c | 3 ++-
arch/sh/kernel/timers/timer-cmt.c | 3 ++-
arch/sh/kernel/timers/timer-mtu2.c | 3 ++-
arch/sh/kernel/timers/timer-tmu.c | 3 ++-
24 files changed, 50 insertions(+), 36 deletions(-)
@@ -10,7 +10,7 @@
struct clk;
struct clk_ops {
- void (*init)(struct clk *clk);
+ int (*init)(struct clk *clk);
void (*enable)(struct clk *clk);
void (*disable)(struct clk *clk);
void (*recalc)(struct clk *clk);
@@ -92,17 +92,6 @@ static void propagate_rate(struct clk *clk)
static int __clk_enable(struct clk *clk)
{
- /*
- * See if this is the first time we're enabling the clock, some
- * clocks that are always enabled still require "special"
- * initialization. This is especially true if the clock mode
- * changes and the clock needs to hunt for the proper set of
- * divisors to use before it can effectively recalc.
- */
- if (unlikely(atomic_read(&clk->kref.refcount) == 1))
- if (clk->ops && clk->ops->init)
- clk->ops->init(clk);
-
kref_get(&clk->kref);
if (clk->flags & CLK_ALWAYS_ENABLED)
@@ -167,6 +156,11 @@ EXPORT_SYMBOL_GPL(clk_disable);
int clk_register(struct clk *clk)
{
+
+ if (clk->ops && clk->ops->init)
+ if (clk->ops->init(clk))
+ return -EINVAL;
+
mutex_lock(&clock_list_sem);
list_add(&clk->node, &clock_list);
@@ -176,8 +170,6 @@ int clk_register(struct clk *clk)
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.");
@@ -29,9 +29,10 @@ static const int pfc_divisors[] = {1,2,0,4};
#error "Illigal Clock Mode!"
#endif
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
+ return 0;
}
static struct clk_ops sh7619_master_clk_ops = {
@@ -32,9 +32,10 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
#error "Illegal Clock Mode!"
#endif
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate = 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+ return 0;
}
static struct clk_ops sh7201_master_clk_ops = {
@@ -37,9 +37,10 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
#error "Illegal Clock Mode!"
#endif
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0003] * PLL2 ;
+ return 0;
}
static struct clk_ops sh7203_master_clk_ops = {
@@ -32,9 +32,10 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
#error "Illigal Clock Mode!"
#endif
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+ return 0;
}
static struct clk_ops sh7206_master_clk_ops = {
@@ -26,12 +26,13 @@ static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 };
static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
int frqcr = ctrl_inw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
clk->rate *= pfc_divisors[idx];
+ return 0;
}
static struct clk_ops sh3_master_clk_ops = {
@@ -30,9 +30,10 @@ static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 };
static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003];
+ return 0;
}
static struct clk_ops sh7705_master_clk_ops = {
@@ -22,12 +22,13 @@ static int stc_multipliers[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
static int ifc_divisors[] = { 1, 2, 4, 1, 3, 1, 1, 1 };
static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
int frqcr = ctrl_inw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
clk->rate *= pfc_divisors[idx];
+ return 0;
}
static struct clk_ops sh7706_master_clk_ops = {
@@ -29,12 +29,13 @@ static void set_bus_parent(struct clk *clk)
clk_put(bus_clk);
}
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
int frqcr = ctrl_inw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
clk->rate *= pfc_divisors[idx];
+ return 0;
}
static struct clk_ops sh7709_master_clk_ops = {
@@ -21,12 +21,13 @@
static int multipliers[] = { 1, 2, 3 };
static int divisors[] = { 1, 2, 3, 4, 6 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
int frqcr = ctrl_inw(FRQCR);
int idx = (frqcr & 0x0300) >> 8;
clk->rate *= multipliers[idx];
+ return 0;
}
static struct clk_ops sh7712_master_clk_ops = {
@@ -66,7 +66,7 @@ static struct clk sh4202_femi_clk = {
.ops = &sh4202_femi_clk_ops,
};
-static void shoc_clk_init(struct clk *clk)
+static int shoc_clk_init(struct clk *clk)
{
int i;
@@ -88,6 +88,7 @@ static void shoc_clk_init(struct clk *clk)
}
WARN_ON(i == ARRAY_SIZE(frqcr3_divisors)); /* Undefined clock */
+ return 0;
}
static void shoc_clk_recalc(struct clk *clk)
@@ -26,9 +26,10 @@ static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 };
#define bfc_divisors ifc_divisors /* Same */
static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007];
+ return 0;
}
static struct clk_ops sh4_master_clk_ops = {
@@ -148,12 +148,13 @@ static void master_clk_recalc(struct clk *clk)
clk->rate = CONFIG_SH_PCLK_FREQ * (((frqcr >> 24) & 0x1f) + 1);
}
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->parent = NULL;
clk->flags |= CLK_RATE_PROPAGATES;
clk->rate = CONFIG_SH_PCLK_FREQ;
master_clk_recalc(clk);
+ return 0;
}
@@ -20,9 +20,10 @@ static int bfc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
static int p0fc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
static int cfc_divisors[] = { 1, 1, 4, 1, 1, 1, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= p0fc_divisors[(ctrl_inl(FRQCR) >> 4) & 0x07];
+ return 0;
}
static struct clk_ops sh7763_master_clk_ops = {
@@ -19,9 +19,10 @@ static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 };
static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f];
+ return 0;
}
static struct clk_ops sh7770_master_clk_ops = {
@@ -20,9 +20,10 @@ static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 };
static int pfc_divisors[] = { 1, 24, 24, 1 };
static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003];
+ return 0;
}
static struct clk_ops sh7780_master_clk_ops = {
@@ -24,9 +24,10 @@ static int mfc_divisors[] = { 1, 1, 4, 6 };
static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18,
24, 32, 36, 48, 1, 1, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f];
+ return 0;
}
static struct clk_ops sh7785_master_clk_ops = {
@@ -27,9 +27,10 @@ static int mfc_divisors[] = { 1, 1, 4, 1 };
static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 16, 1,
24, 32, 1, 48, 1, 1, 1, 1 };
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f];
+ return 0;
}
static struct clk_ops sh7786_master_clk_ops = {
@@ -31,9 +31,10 @@ static int cfc_divisors[] = { 1, 1, 4, 6 };
#define PFC_POS 0
#define CFC_POS 20
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK];
+ return 0;
}
static struct clk_ops shx3_master_clk_ops = {
@@ -22,10 +22,11 @@ static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
static unsigned long cprc_base;
-static void master_clk_init(struct clk *clk)
+static int master_clk_init(struct clk *clk)
{
int idx = (ctrl_inl(cprc_base + 0x00) >> 6) & 0x0007;
clk->rate *= ifc_table[idx];
+ return 0;
}
static struct clk_ops sh5_master_clk_ops = {
@@ -112,13 +112,14 @@ static struct irqaction cmt_irq = {
.mask = CPU_MASK_NONE,
};
-static void cmt_clk_init(struct clk *clk)
+static int cmt_clk_init(struct clk *clk)
{
u8 divisor = CMT_CMCSR_INIT & 0x3;
ctrl_inw(CMT_CMCSR_0);
ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0);
clk->parent = clk_get(NULL, "module_clk");
clk->rate = clk->parent->rate / (8 << (divisor << 1));
+ return 0;
}
static void cmt_clk_recalc(struct clk *clk)
@@ -120,7 +120,7 @@ static struct irqaction mtu2_irq = {
static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 };
-static void mtu2_clk_init(struct clk *clk)
+static int mtu2_clk_init(struct clk *clk)
{
u8 idx = MTU2_TCR_INIT & 0x7;
@@ -128,6 +128,7 @@ static void mtu2_clk_init(struct clk *clk)
/* Start TCNT counting */
ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR);
+ return 0;
}
static void mtu2_clk_recalc(struct clk *clk)
@@ -165,12 +165,13 @@ static struct irqaction tmu0_irq = {
.mask = CPU_MASK_NONE,
};
-static void __init tmu_clk_init(struct clk *clk)
+static int __init tmu_clk_init(struct clk *clk)
{
u8 divisor = TMU_TCR_INIT & 0x7;
int tmu_num = clk->name[3]-'0';
ctrl_outw(TMU_TCR_INIT, TMU0_TCR+(tmu_num*0xC));
clk->rate = clk_get_rate(clk->parent) / (4 << (divisor << 1));
+ return 0;
}
static void tmu_clk_recalc(struct clk *clk)
--
1.5.6.6