diff options
author | Doug Anderson <dianders@chromium.org> | 2012-11-27 14:53:14 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-11-28 12:24:22 -0500 |
commit | 5b7897db00bd66a42c626012f51cd3b1d5e6bee5 (patch) | |
tree | 9532e9f4916cbdc3a7a3024b7122c15b3b2fde24 /arch/arm/mach-exynos | |
parent | 7423d2d817b815cc5bc41316f4aaa8ace3c4153e (diff) |
ARM: EXYNOS: Avoid early use of of_machine_is_compatible()
The recent commit "ARM: EXYNOS: add support for EXYNOS5440 SoC" broke
support for exynos5250 because of_machine_is_compatible() was used too
early in the boot process. It also probably meant that the exynos5440
failed to use the proper iotable. Switch to use
of_flat_dt_is_compatible() in both of these cases.
The failure I was seeing in exynos5250 because of this was:
Division by zero in kernel.
[<80015ed4>] (unwind_backtrace+0x0/0xec) from [<8045c7a4>] (dump_stack+0x20/0x24)
[<8045c7a4>] (dump_stack+0x20/0x24) from [<80012990>] (__div0+0x20/0x28)
[<80012990>] (__div0+0x20/0x28) from [<8021ab04>] (Ldiv0_64+0x8/0x18)
[<8021ab04>] (Ldiv0_64+0x8/0x18) from [<80068560>] (__clocksource_updatefreq_scale+0x54/0x134)
[<80068560>] (__clocksource_updatefreq_scale+0x54/0x134) from [<8006865c>] (__clocksource_register_scale+0x1c/0x54)
[<8006865c>] (__clocksource_register_scale+0x1c/0x54) from [<80612a18>] (exynos_timer_init+0x100/0x1e8)
[<80612a18>] (exynos_timer_init+0x100/0x1e8) from [<8060d184>] (time_init+0x28/0x38)
[<8060d184>] (time_init+0x28/0x38) from [<8060a754>] (start_kernel+0x1e0/0x3c8)
[<8060a754>] (start_kernel+0x1e0/0x3c8) from [<40008078>] (0x40008078)
Signed-off-by: Doug Anderson <dianders@chromium.org>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
[olofj: fixed two build errors, one missing include and one !CONFIG_OF failure]
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-exynos')
-rw-r--r-- | arch/arm/mach-exynos/common.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mach-exynos5-dt.c | 5 |
2 files changed, 19 insertions, 5 deletions
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 94f1dedc0617..68b4b8eb63dc 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/serial_core.h> | 19 | #include <linux/serial_core.h> |
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_fdt.h> | ||
21 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
22 | #include <linux/export.h> | 23 | #include <linux/export.h> |
23 | #include <linux/irqdomain.h> | 24 | #include <linux/irqdomain.h> |
@@ -121,6 +122,7 @@ static struct map_desc exynos_iodesc[] __initdata = { | |||
121 | }, | 122 | }, |
122 | }; | 123 | }; |
123 | 124 | ||
125 | #ifdef CONFIG_ARCH_EXYNOS5 | ||
124 | static struct map_desc exynos5440_iodesc[] __initdata = { | 126 | static struct map_desc exynos5440_iodesc[] __initdata = { |
125 | { | 127 | { |
126 | .virtual = (unsigned long)S5P_VA_CHIPID, | 128 | .virtual = (unsigned long)S5P_VA_CHIPID, |
@@ -129,6 +131,7 @@ static struct map_desc exynos5440_iodesc[] __initdata = { | |||
129 | .type = MT_DEVICE, | 131 | .type = MT_DEVICE, |
130 | }, | 132 | }, |
131 | }; | 133 | }; |
134 | #endif | ||
132 | 135 | ||
133 | static struct map_desc exynos4_iodesc[] __initdata = { | 136 | static struct map_desc exynos4_iodesc[] __initdata = { |
134 | { | 137 | { |
@@ -346,11 +349,19 @@ void __init exynos_init_late(void) | |||
346 | 349 | ||
347 | void __init exynos_init_io(struct map_desc *mach_desc, int size) | 350 | void __init exynos_init_io(struct map_desc *mach_desc, int size) |
348 | { | 351 | { |
352 | struct map_desc *iodesc = exynos_iodesc; | ||
353 | int iodesc_sz = ARRAY_SIZE(exynos_iodesc); | ||
354 | #if defined(CONFIG_OF) && defined(CONFIG_ARCH_EXYNOS5) | ||
355 | unsigned long root = of_get_flat_dt_root(); | ||
356 | |||
349 | /* initialize the io descriptors we need for initialization */ | 357 | /* initialize the io descriptors we need for initialization */ |
350 | if (of_machine_is_compatible("samsung,exynos5440")) | 358 | if (of_flat_dt_is_compatible(root, "samsung,exynos5440")) { |
351 | iotable_init(exynos5440_iodesc, ARRAY_SIZE(exynos5440_iodesc)); | 359 | iodesc = exynos5440_iodesc; |
352 | else | 360 | iodesc_sz = ARRAY_SIZE(exynos5440_iodesc); |
353 | iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc)); | 361 | } |
362 | #endif | ||
363 | |||
364 | iotable_init(iodesc, iodesc_sz); | ||
354 | 365 | ||
355 | if (mach_desc) | 366 | if (mach_desc) |
356 | iotable_init(mach_desc, size); | 367 | iotable_init(mach_desc, size); |
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 4db2ee1238b4..f1326be80b91 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/of_platform.h> | 12 | #include <linux/of_platform.h> |
13 | #include <linux/of_fdt.h> | ||
13 | #include <linux/serial_core.h> | 14 | #include <linux/serial_core.h> |
14 | 15 | ||
15 | #include <asm/mach/arch.h> | 16 | #include <asm/mach/arch.h> |
@@ -83,9 +84,11 @@ static const struct of_dev_auxdata exynos5440_auxdata_lookup[] __initconst = { | |||
83 | 84 | ||
84 | static void __init exynos5_dt_map_io(void) | 85 | static void __init exynos5_dt_map_io(void) |
85 | { | 86 | { |
87 | unsigned long root = of_get_flat_dt_root(); | ||
88 | |||
86 | exynos_init_io(NULL, 0); | 89 | exynos_init_io(NULL, 0); |
87 | 90 | ||
88 | if (of_machine_is_compatible("samsung,exynos5250")) | 91 | if (of_flat_dt_is_compatible(root, "samsung,exynos5250")) |
89 | s3c24xx_init_clocks(24000000); | 92 | s3c24xx_init_clocks(24000000); |
90 | } | 93 | } |
91 | 94 | ||