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 | ||
