diff mbox

[RFC,05/12] ARM: Add DT support to decompressor tags

Message ID 20120715024609.513918780@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Domenico Andreoli July 15, 2012, 2:44 a.m. UTC
From: Domenico Andreoli <domenico.andreoli@linux.com>

Thinking at multiplatform kernels we cannot miss DeviceTrees. So here we
add some new glue to select tags also using dt_compat fields, mandatory
in case of pure DT boards without numeric machine id.

Note the care required to pack, relocate and unpack all those strings.

Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
 arch/arm/boot/compressed/Makefile       |    2 --
 arch/arm/boot/compressed/arch.c         |   24 ++++++++++++++++++++++++
 arch/arm/boot/compressed/atags_to_fdt.c |   15 +++++++++++++++
 include/linux/decompress/arch.h         |    1 +
 4 files changed, 40 insertions(+), 2 deletions(-)

Comments

Arnd Bergmann July 17, 2012, 2:14 p.m. UTC | #1
On Sunday 15 July 2012, Domenico Andreoli wrote:
> -ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
>  OBJS   += $(libfdt_objs) atags_to_fdt.o
> -endif

Can you explain why this is necessary? I don't see any code
of that file being called from the newly added code for the
case where CONFIG_ARM_ATAG_DTB_COMPAT is disabled.

	Arnd
Domenico Andreoli July 17, 2012, 2:41 p.m. UTC | #2
On Tue, Jul 17, 2012 at 02:14:19PM +0000, Arnd Bergmann wrote:
> On Sunday 15 July 2012, Domenico Andreoli wrote:
> > -ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
> >  OBJS   += $(libfdt_objs) atags_to_fdt.o
> > -endif
> 
> Can you explain why this is necessary? I don't see any code
> of that file being called from the newly added code for the
> case where CONFIG_ARM_ATAG_DTB_COMPAT is disabled.

I put function get_fdt_prop() in atags_to_fdt.c but what I basically needed
was the inclusion of $(libfdt_objs). I agree this can be achieved out of
CONFIG_ARM_ATAG_DTB_COMPAT's stuff and I'll do if the patchest is allowed
to mature.

I guess a better place could be libfdt itself but feel free to suggest a
better one.

Thanks,
Domenico
diff mbox

Patch

Index: b/arch/arm/boot/compressed/atags_to_fdt.c
===================================================================
--- a/arch/arm/boot/compressed/atags_to_fdt.c
+++ b/arch/arm/boot/compressed/atags_to_fdt.c
@@ -97,3 +97,18 @@  int atags_to_fdt(void *atag_list, void *
 
 	return fdt_pack(fdt);
 }
+
+const char *get_fdt_prop(void *fdt, const char *path, const char *prop)
+{
+	int len, offset;
+
+	/* if we don't get a DTB here we're done already */
+	if (*(u32 *) fdt != fdt32_to_cpu(FDT_MAGIC))
+		return NULL;
+
+	offset = fdt_path_offset(fdt, path);
+	if (offset < 0)
+		return NULL;
+
+	return fdt_getprop(fdt, offset, prop, &len);
+}
Index: b/arch/arm/boot/compressed/arch.c
===================================================================
--- a/arch/arm/boot/compressed/arch.c
+++ b/arch/arm/boot/compressed/arch.c
@@ -24,6 +24,8 @@  unsigned int __machine_arch_type;
 
 #include "arch.h"
 
+const char *get_fdt_prop(void *fdt, const char *path, const char *prop);
+
 unsigned long free_mem_ptr;
 unsigned long free_mem_end_ptr;
 
@@ -57,6 +59,15 @@  extern const struct decomp_tag_hdr __dec
 	     (p) < __decomp_tags_end;           \
 	     p = ((void *) p) + (p)->size)
 
+static bool is_compatible(const char (*dt_compat)[16], const char *compatible)
+{
+	for ( ; strlen(*dt_compat); dt_compat++)
+		if (!strcmp(*dt_compat, compatible))
+			return true;
+
+	return false;
+}
+
 void arch_setup(unsigned int arch_id, void *atag_fdt,
 		unsigned long free_mem_ptr_p,
 		unsigned long free_mem_ptr_end_p)
@@ -65,7 +76,11 @@  void arch_setup(unsigned int arch_id, vo
 	const struct decomp_tag_hdr *hdr;
 	void (*arch_setup_p)(void);
 
+	const char (*dt_compat)[16];
+	const char *compatible;
+
 	__machine_arch_type = arch_id;
+	compatible = get_fdt_prop(atag_fdt, "/", "compatible");
 
 	arch_setup_p = fallback_arch_setup;
 	arch_error_p = fallback_arch_error;
@@ -77,6 +92,15 @@  void arch_setup(unsigned int arch_id, vo
 		if (hdr->arch_id != arch_id)
 			continue;
 
+		/*
+		 * In case of DT entry, further inspection of the dt_compat
+		 * table is required before accepting the tag.
+		 */
+		dt_compat = (const char (*)[16]) fix_data_ptr(hdr->dt_compat);
+		if (arch_id == ~0 && compatible && dt_compat &&
+		    !is_compatible(dt_compat, compatible))
+			continue;
+
 		if (hdr->type == DECOMP_TAG_ARCH) {
 			arch_tag = (struct decomp_arch_tag *) hdr;
 			arch_setup_p = fix_text_ptr(arch_tag->setup);
Index: b/include/linux/decompress/arch.h
===================================================================
--- a/include/linux/decompress/arch.h
+++ b/include/linux/decompress/arch.h
@@ -24,6 +24,7 @@  enum decomp_tag_type {
 
 struct decomp_tag_hdr {
 	unsigned int arch_id;
+	const char (*dt_compat)[16];
 	unsigned short type;
 	unsigned short size;
 };
Index: b/arch/arm/boot/compressed/Makefile
===================================================================
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -107,9 +107,7 @@  $(addprefix $(obj)/,$(libfdt) $(libfdt_h
 $(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
 	$(addprefix $(obj)/,$(libfdt_hdrs))
 
-ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
 OBJS	+= $(libfdt_objs) atags_to_fdt.o
-endif
 
 targets       := vmlinux vmlinux.lds \
 		 piggy.$(suffix_y) piggy.$(suffix_y).o \