diff options
author | Paul Walmsley <paul@pwsan.com> | 2009-04-22 21:48:53 -0400 |
---|---|---|
committer | paul <paul@twilight.(none)> | 2009-04-22 21:48:53 -0400 |
commit | c8088112fd96ad8b0f0bcd2f168fe6a17bf3cb41 (patch) | |
tree | e060184cd9a69f446c3b12317a2e8e249c72d32e /arch | |
parent | 577c9c456f0e1371cbade38eaf91ae8e8a308555 (diff) |
OMAP2xxx clock: pre-initialize struct clks early
Commit 3f0a820c4c0b4670fb5f164baa5582e23c2ef118 breaks OMAP2xxx boot
during initial propagate_rate() on osc_ck and sys_ck. Fix by
pre-initializing all struct clks before running any other clock init
code. Incorporates review comments from Russell King
<rmk+kernel@arm.linux.org.uk>.
Resolves
<1>Unable to handle kernel NULL pointer dereference at virtual address 00000000
<1>pgd = c0004000
<1>[00000000] *pgd=00000000
Internal error: Oops: 5 [#1]
Modules linked in:
CPU: 0 Not tainted (2.6.29-omap1 #37)
PC is at propagate_rate+0x10/0x60
LR is at omap2_clk_init+0x30/0x218
...
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Tested-by: Jarkko Nikula <jarkko.nikula@nokia.com>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/clock24xx.c | 6 | ||||
-rw-r--r-- | arch/arm/plat-omap/clock.c | 7 |
2 files changed, 10 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index 1e839c5a28c5..984fb86349ba 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c | |||
@@ -720,14 +720,14 @@ int __init omap2_clk_init(void) | |||
720 | 720 | ||
721 | clk_init(&omap2_clk_functions); | 721 | clk_init(&omap2_clk_functions); |
722 | 722 | ||
723 | for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) | ||
724 | clk_init_one(c->lk.clk); | ||
725 | |||
723 | osc_ck.rate = omap2_osc_clk_recalc(&osc_ck); | 726 | osc_ck.rate = omap2_osc_clk_recalc(&osc_ck); |
724 | propagate_rate(&osc_ck); | 727 | propagate_rate(&osc_ck); |
725 | sys_ck.rate = omap2_sys_clk_recalc(&sys_ck); | 728 | sys_ck.rate = omap2_sys_clk_recalc(&sys_ck); |
726 | propagate_rate(&sys_ck); | 729 | propagate_rate(&sys_ck); |
727 | 730 | ||
728 | for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) | ||
729 | clk_init_one(c->lk.clk); | ||
730 | |||
731 | cpu_mask = 0; | 731 | cpu_mask = 0; |
732 | if (cpu_is_omap2420()) | 732 | if (cpu_is_omap2420()) |
733 | cpu_mask |= CK_242X; | 733 | cpu_mask |= CK_242X; |
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 2e0614552ac8..29efc279287a 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -239,6 +239,13 @@ void recalculate_root_clocks(void) | |||
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
242 | /** | ||
243 | * clk_init_one - initialize any fields in the struct clk before clk init | ||
244 | * @clk: struct clk * to initialize | ||
245 | * | ||
246 | * Initialize any struct clk fields needed before normal clk initialization | ||
247 | * can run. No return value. | ||
248 | */ | ||
242 | void clk_init_one(struct clk *clk) | 249 | void clk_init_one(struct clk *clk) |
243 | { | 250 | { |
244 | INIT_LIST_HEAD(&clk->children); | 251 | INIT_LIST_HEAD(&clk->children); |