diff options
author | Magnus Damm <damm@opensource.se> | 2012-05-10 01:57:22 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-05-12 16:13:38 -0400 |
commit | b759bd114e27fbb940fb44fd16552e8f4acd831e (patch) | |
tree | aabfb18091281cc5af1df1e76a5ebdbc7bcd5a75 | |
parent | 173e2fec4d9e950ee5e4bba272091e248a961c98 (diff) |
ARM / mach-shmobile: r8a7779 SMP TWD boot regression fix
Fix SMP TWD boot regression on r8a7779 based platforms caused by:
4200b16 ARM: shmobile: convert to twd_local_timer_register() interface
After the merge of the above commit it has been impossible to boot
r8a7779 based SoCs with SMP enabled and CONFIG_HAVE_ARM_TWD=y. The
kernel crashes at smp_init_cpus() timing which is before the console
has been initialized, so to the user this looks like a kernel lock up
without any particular error message.
This patch fixes the regression on r8a7779 by moving the TWD
registration code from smp_init_cpus() to sys_timer->init() time.
Signed-off-by: Magnus Damm <damm@opensource.se>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-r8a7779.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/smp-r8a7779.c | 8 |
3 files changed, 12 insertions, 1 deletions
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 83ad3fe0a75f..18ac8251a26a 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h | |||
@@ -82,5 +82,6 @@ extern int r8a7779_platform_cpu_kill(unsigned int cpu); | |||
82 | extern void r8a7779_secondary_init(unsigned int cpu); | 82 | extern void r8a7779_secondary_init(unsigned int cpu); |
83 | extern int r8a7779_boot_secondary(unsigned int cpu); | 83 | extern int r8a7779_boot_secondary(unsigned int cpu); |
84 | extern void r8a7779_smp_prepare_cpus(void); | 84 | extern void r8a7779_smp_prepare_cpus(void); |
85 | extern void r8a7779_register_twd(void); | ||
85 | 86 | ||
86 | #endif /* __ARCH_MACH_COMMON_H */ | 87 | #endif /* __ARCH_MACH_COMMON_H */ |
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 12c6f529ab89..e98e46f6cf55 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c | |||
@@ -262,10 +262,14 @@ void __init r8a7779_add_standard_devices(void) | |||
262 | ARRAY_SIZE(r8a7779_late_devices)); | 262 | ARRAY_SIZE(r8a7779_late_devices)); |
263 | } | 263 | } |
264 | 264 | ||
265 | /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ | ||
266 | void __init __weak r8a7779_register_twd(void) { } | ||
267 | |||
265 | static void __init r8a7779_earlytimer_init(void) | 268 | static void __init r8a7779_earlytimer_init(void) |
266 | { | 269 | { |
267 | r8a7779_clock_init(); | 270 | r8a7779_clock_init(); |
268 | shmobile_earlytimer_init(); | 271 | shmobile_earlytimer_init(); |
272 | r8a7779_register_twd(); | ||
269 | } | 273 | } |
270 | 274 | ||
271 | void __init r8a7779_add_early_devices(void) | 275 | void __init r8a7779_add_early_devices(void) |
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index b62e19d4c9af..6d1d0238cbf7 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c | |||
@@ -64,8 +64,15 @@ static void __iomem *scu_base_addr(void) | |||
64 | static DEFINE_SPINLOCK(scu_lock); | 64 | static DEFINE_SPINLOCK(scu_lock); |
65 | static unsigned long tmp; | 65 | static unsigned long tmp; |
66 | 66 | ||
67 | #ifdef CONFIG_HAVE_ARM_TWD | ||
67 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); | 68 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); |
68 | 69 | ||
70 | void __init r8a7779_register_twd(void) | ||
71 | { | ||
72 | twd_local_timer_register(&twd_local_timer); | ||
73 | } | ||
74 | #endif | ||
75 | |||
69 | static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) | 76 | static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) |
70 | { | 77 | { |
71 | void __iomem *scu_base = scu_base_addr(); | 78 | void __iomem *scu_base = scu_base_addr(); |
@@ -84,7 +91,6 @@ unsigned int __init r8a7779_get_core_count(void) | |||
84 | { | 91 | { |
85 | void __iomem *scu_base = scu_base_addr(); | 92 | void __iomem *scu_base = scu_base_addr(); |
86 | 93 | ||
87 | shmobile_twd_init(&twd_local_timer); | ||
88 | return scu_get_core_count(scu_base); | 94 | return scu_get_core_count(scu_base); |
89 | } | 95 | } |
90 | 96 | ||