summaryrefslogtreecommitdiff
path: root/arch/mips/cavium-octeon/setup.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2012-09-05 09:57:19 +0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-09-05 09:57:19 +0400
commite6c340171f0daaccc95b90abbeed2b837157ee11 (patch)
tree843d4035be59bd791321910e52157ce527b3b4b3 /arch/mips/cavium-octeon/setup.c
parenta85442ade272121927a56e02f7dfde1127482df2 (diff)
parent4cbe5a555fa58a79b6ecbb6c531b8bab0650778d (diff)
downloadlinux-e6c340171f0daaccc95b90abbeed2b837157ee11.tar.xz
Merge tag 'v3.6-rc4' into next
Linux 3.6-rc4 # gpg: Signature made Sat 01 Sep 2012 10:40:33 AM PDT using RSA key ID 00411886 # gpg: Good signature from "Linus Torvalds <torvalds@linux-foundation.org>"
Diffstat (limited to 'arch/mips/cavium-octeon/setup.c')
-rw-r--r--arch/mips/cavium-octeon/setup.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 260dc247c052..919b0fb7bb1a 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -21,6 +21,8 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#include <asm/processor.h>
#include <asm/reboot.h>
@@ -775,3 +777,46 @@ void prom_free_prom_memory(void)
}
#endif
}
+
+int octeon_prune_device_tree(void);
+
+extern const char __dtb_octeon_3xxx_begin;
+extern const char __dtb_octeon_3xxx_end;
+extern const char __dtb_octeon_68xx_begin;
+extern const char __dtb_octeon_68xx_end;
+void __init device_tree_init(void)
+{
+ int dt_size;
+ struct boot_param_header *fdt;
+ bool do_prune;
+
+ if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
+ fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
+ if (fdt_check_header(fdt))
+ panic("Corrupt Device Tree passed to kernel.");
+ dt_size = be32_to_cpu(fdt->totalsize);
+ do_prune = false;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
+ fdt = (struct boot_param_header *)&__dtb_octeon_68xx_begin;
+ dt_size = &__dtb_octeon_68xx_end - &__dtb_octeon_68xx_begin;
+ do_prune = true;
+ } else {
+ fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin;
+ dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin;
+ do_prune = true;
+ }
+
+ /* Copy the default tree from init memory. */
+ initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8);
+ if (initial_boot_params == NULL)
+ panic("Could not allocate initial_boot_params\n");
+ memcpy(initial_boot_params, fdt, dt_size);
+
+ if (do_prune) {
+ octeon_prune_device_tree();
+ pr_info("Using internal Device Tree.\n");
+ } else {
+ pr_info("Using passed Device Tree.\n");
+ }
+ unflatten_device_tree();
+}