arm: Add devicetree fixup machine function
authorLaura Abbott <lauraa@codeaurora.org>
Tue, 15 Jul 2014 17:03:36 +0000 (10:03 -0700)
committerGrant Likely <grant.likely@linaro.org>
Wed, 30 Jul 2014 03:26:49 +0000 (21:26 -0600)
Commit 1c2f87c22566cd057bc8cde10c37ae9da1a1bb76
(ARM: 8025/1: Get rid of meminfo) dropped the upper bound on
the number of memory banks that can be added as there was no
technical need in the kernel. It turns out though, some bootloaders
(specifically the arndale-octa exynos boards) may pass invalid memory
information and rely on the kernel to not parse this data. This is a
bug in the bootloader but we still need to work around this.
Work around this by introducing a dt_fixup function. This function
gets called before the flattened devicetree is scanned for memory
and the like. In this fixup function for exynos, limit the maximum
number of memory regions in the devicetree.

Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
Tested-by: Andreas Färber <afaerber@suse.de>
[glikely: Added a comment and fixed up function name]
Signed-off-by: Grant Likely <grant.likely@linaro.org>
arch/arm/include/asm/mach/arch.h
arch/arm/kernel/devtree.c
arch/arm/mach-exynos/exynos.c

index 060a75e99263dd3613fb40eb1bf43998cae433d1..0406cb3f1af765685da88c54433b80737bc70152 100644 (file)
@@ -50,6 +50,7 @@ struct machine_desc {
        struct smp_operations   *smp;           /* SMP operations       */
        bool                    (*smp_init)(void);
        void                    (*fixup)(struct tag *, char **);
+       void                    (*dt_fixup)(void);
        void                    (*init_meminfo)(void);
        void                    (*reserve)(void);/* reserve mem blocks  */
        void                    (*map_io)(void);/* IO mapping function  */
index e94a157ddff11dca08e81e7182652c24d4d56a49..11c54de9f8cfa1e6227ea38dcfddddf2f67ee403 100644 (file)
@@ -212,7 +212,7 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
        mdesc_best = &__mach_desc_GENERIC_DT;
 #endif
 
-       if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys)))
+       if (!dt_phys || !early_init_dt_verify(phys_to_virt(dt_phys)))
                return NULL;
 
        mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);
@@ -237,6 +237,12 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
                dump_machine_table(); /* does not return */
        }
 
+       /* We really don't want to do this, but sometimes firmware provides buggy data */
+       if (mdesc->dt_fixup)
+               mdesc->dt_fixup();
+
+       early_init_dt_scan_nodes();
+
        /* Change machine number to match the mdesc we're using */
        __machine_arch_type = mdesc->nr;
 
index 46d893fcbe8538ecccea346715487a66d3cc1e01..66c9b9614f3cce2d9bcd5f75ff344a67f81caa8e 100644 (file)
@@ -335,6 +335,15 @@ static void __init exynos_reserve(void)
 #endif
 }
 
+static void __init exynos_dt_fixup(void)
+{
+       /*
+        * Some versions of uboot pass garbage entries in the memory node,
+        * use the old CONFIG_ARM_NR_BANKS
+        */
+       of_fdt_limit_memory(8);
+}
+
 DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
        /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
        /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
@@ -348,4 +357,5 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
        .dt_compat      = exynos_dt_compat,
        .restart        = exynos_restart,
        .reserve        = exynos_reserve,
+       .dt_fixup       = exynos_dt_fixup,
 MACHINE_END