msm: clock: Split up struct clock_init_data's init() functions
clock_init_data's init() function was called at the start of
msm_clock_init(), before looping through the clocks to set up parents
and perform handoff operations. This meant that performing certain
operations (ex. clk_set_rate()) in init() could interfere with the
handoff process by modifying the clock's registers before the handoff
code had a chance to examine them. It also meant that operations
done in init() would not take into account clock parent relationships,
making it an inappropriate place to set the rates of voter clocks or
enable clocks with parents.
Address this problem by splitting the init() function into two optional
parts: a pre_init() function that executes before clock driver
initialization, and a post_init() function that executes after driver
initialization.
pre_init() is the appropriate place to perform any register or system
configuration that should be done before clock driver initializes or
handoff if performed. Clock APIs should not be called from within it.
post_init() is the appropriate place to perform any additional
configuration that requires the clock driver already be initialized.
Clock APIs can be called within it.
Change-Id: I4b6de87eeee02a86717f53fd42d22e811b10b3f7
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index a2882a5..31ba6b7 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -2965,8 +2965,7 @@
{USBH3_NS_REG, BIT(6), BIT(6)},
};
-/* Local clock driver initialization. */
-static void __init msm7x30_clock_init(void)
+static void __init msm7x30_clock_pre_init(void)
{
int i;
uint32_t val;
@@ -2979,15 +2978,17 @@
* function is a NOP since writes to shadow regions that we don't own
* are ignored. */
- clk_set_rate(&usb_hs_src_clk.c, clk_tbl_usb[1].freq_hz);
-
for (i = 0; i < ARRAY_SIZE(ri_list); i++) {
val = readl_relaxed(ri_list[i].reg);
val &= ~ri_list[i].mask;
val |= ri_list[i].val;
writel_relaxed(val, ri_list[i].reg);
}
+}
+static void __init msm7x30_clock_post_init(void)
+{
+ clk_set_rate(&usb_hs_src_clk.c, 60000000);
clk_set_rate(&i2c_clk.c, 19200000);
clk_set_rate(&i2c_2_clk.c, 19200000);
clk_set_rate(&qup_i2c_clk.c, 19200000);
@@ -3006,7 +3007,8 @@
struct clock_init_data msm7x30_clock_init_data __initdata = {
.table = msm_clocks_7x30,
.size = ARRAY_SIZE(msm_clocks_7x30),
- .init = msm7x30_clock_init,
+ .pre_init = msm7x30_clock_pre_init,
+ .post_init = msm7x30_clock_post_init,
};
/*
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 044bd79..417b388 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5996,12 +5996,8 @@
}
}
-/* Local clock driver initialization. */
-static void __init msm8960_clock_init(void)
+static void __init msm8960_clock_pre_init(void)
{
- /* Keep PXO on whenever APPS cpu is active */
- clk_prepare_enable(&pxo_a_clk.c);
-
if (cpu_is_apq8064()) {
vdd_sr2_pll.set_vdd = set_vdd_sr2_pll_8064;
} else if (cpu_is_msm8930() || cpu_is_msm8627()) {
@@ -6050,6 +6046,12 @@
/* Initialize clock registers. */
reg_init();
+}
+
+static void __init msm8960_clock_post_init(void)
+{
+ /* Keep PXO on whenever APPS cpu is active */
+ clk_prepare_enable(&pxo_a_clk.c);
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 27000000);
@@ -6131,20 +6133,23 @@
struct clock_init_data msm8960_clock_init_data __initdata = {
.table = msm_clocks_8960,
.size = ARRAY_SIZE(msm_clocks_8960),
- .init = msm8960_clock_init,
+ .pre_init = msm8960_clock_pre_init,
+ .post_init = msm8960_clock_post_init,
.late_init = msm8960_clock_late_init,
};
struct clock_init_data apq8064_clock_init_data __initdata = {
.table = msm_clocks_8064,
.size = ARRAY_SIZE(msm_clocks_8064),
- .init = msm8960_clock_init,
+ .pre_init = msm8960_clock_pre_init,
+ .post_init = msm8960_clock_post_init,
.late_init = msm8960_clock_late_init,
};
struct clock_init_data msm8930_clock_init_data __initdata = {
.table = msm_clocks_8930,
.size = ARRAY_SIZE(msm_clocks_8930),
- .init = msm8960_clock_init,
+ .pre_init = msm8960_clock_pre_init,
+ .post_init = msm8960_clock_post_init,
.late_init = msm8960_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index c2632ee..0fab04e 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3751,8 +3751,10 @@
writel_relaxed(regval, reg);
}
-static void __init reg_init(void)
+static void __init msm8660_clock_pre_init(void)
{
+ vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+
/* Setup MM_PLL2 (PLL3), but turn it off. Rate set by set_rate_tv(). */
rmwreg(0, MM_PLL2_MODE_REG, BIT(0)); /* Disable output */
/* Set ref, bypass, assert reset, disable output, disable test mode */
@@ -3836,14 +3838,10 @@
rmwreg(0x400001, MISC_CC2_REG, 0x424003);
}
-/* Local clock driver initialization. */
-static void __init msm8660_clock_init(void)
+static void __init msm8660_clock_post_init(void)
{
- vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
/* Keep PXO on whenever APPS cpu is active */
clk_prepare_enable(&pxo_a_clk.c);
- /* Initialize clock registers. */
- reg_init();
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 27000000);
@@ -3885,6 +3883,7 @@
struct clock_init_data msm8x60_clock_init_data __initdata = {
.table = msm_clocks_8x60,
.size = ARRAY_SIZE(msm_clocks_8x60),
- .init = msm8660_clock_init,
+ .pre_init = msm8660_clock_pre_init,
+ .post_init = msm8660_clock_post_init,
.late_init = msm8660_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index cc71c0b..72a9eab 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1739,10 +1739,14 @@
/*
* Miscellaneous clock register initializations
*/
-static void __init reg_init(void)
+static void __init msm9615_clock_pre_init(void)
{
u32 regval, is_pll_enabled, pll9_lval;
+ vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+
+ clk_ops_pll.enable = sr_pll_clk_enable;
+
/* Enable PDM CXO source. */
regval = readl_relaxed(PDM_CLK_NS_REG);
writel_relaxed(BIT(13) | regval, PDM_CLK_NS_REG);
@@ -1831,18 +1835,11 @@
writel_relaxed(regval, DMA_BAM_HCLK_CTL);
}
-/* Local clock driver initialization. */
-static void __init msm9615_clock_init(void)
+static void __init msm9615_clock_post_init(void)
{
- vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
/* Keep CXO on whenever APPS cpu is active */
clk_prepare_enable(&cxo_a_clk.c);
- clk_ops_pll.enable = sr_pll_clk_enable;
-
- /* Initialize clock registers. */
- reg_init();
-
/* Initialize rates for clocks that only support one. */
clk_set_rate(&pdm_clk.c, 19200000);
clk_set_rate(&prng_clk.c, 32000000);
@@ -1868,6 +1865,7 @@
struct clock_init_data msm9615_clock_init_data __initdata = {
.table = msm_clocks_9615,
.size = ARRAY_SIZE(msm_clocks_9615),
- .init = msm9615_clock_init,
+ .pre_init = msm9615_clock_pre_init,
+ .post_init = msm9615_clock_post_init,
.late_init = msm9615_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
index a0defe3..ed3b8c2 100644
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -307,7 +307,7 @@
struct clock_init_data msm7x27_clock_init_data __initdata = {
.table = msm_clocks_7x27,
.size = ARRAY_SIZE(msm_clocks_7x27),
- .init = msm_shared_pll_control_init,
+ .pre_init = msm_shared_pll_control_init,
};
/* Clock table for common clocks between 7627a and 7625a */
@@ -413,7 +413,7 @@
static struct clk_lookup msm_clk_7627a_7625a[ARRAY_SIZE(msm_cmn_clk_7625a_7627a)
+ ARRAY_SIZE(msm_clk_7627a)];
-static void __init msm7627a_clock_init(void)
+static void __init msm7627a_clock_pre_init(void)
{
int size = ARRAY_SIZE(msm_cmn_clk_7625a_7627a);
@@ -432,7 +432,7 @@
struct clock_init_data msm7x27a_clock_init_data __initdata = {
.table = msm_clk_7627a_7625a,
- .init = msm7627a_clock_init,
+ .pre_init = msm7627a_clock_pre_init,
};
static struct clk_lookup msm_clocks_8x50[] = {
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 884a27e..1776c12 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -401,8 +401,8 @@
size_t num_clocks;
clk_init_data = data;
- if (clk_init_data->init)
- clk_init_data->init();
+ if (clk_init_data->pre_init)
+ clk_init_data->pre_init();
clock_tbl = data->table;
num_clocks = data->size;
@@ -420,6 +420,9 @@
}
clkdev_add_table(clock_tbl, num_clocks);
+
+ if (clk_init_data->post_init)
+ clk_init_data->post_init();
}
/*
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 785e838..a70dbd1 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -126,13 +126,15 @@
* struct clock_init_data - SoC specific clock initialization data
* @table: table of lookups to add
* @size: size of @table
- * @init: called before registering @table
+ * @pre_init: called before initializing the clock driver.
+ * @post_init: called after registering @table. clock APIs can be called inside.
* @late_init: called during late init
*/
struct clock_init_data {
struct clk_lookup *table;
size_t size;
- void (*init)(void);
+ void (*pre_init)(void);
+ void (*post_init)(void);
int (*late_init)(void);
};