Signed-off-by: Graeme Russ <graeme.r...@gmail.com>
---
 Makefile             |   34 ++-
 common/Makefile      |    2 +
 config.mk            |    2 +
 doc/README.INIT_FUNC |   65 +++
 include/init_func.h  |   37 ++
 tools/Makefile       |    6 +
 tools/mkinitseq.c    | 1512 ++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 1657 insertions(+), 1 deletions(-)
 create mode 100644 doc/README.INIT_FUNC
 create mode 100644 include/init_func.h
 create mode 100644 tools/mkinitseq.c

diff --git a/Makefile b/Makefile
index cdd4294..62d9f81 100644
--- a/Makefile
+++ b/Makefile
@@ -467,8 +467,40 @@ GEN_UBOOT = \
                        -Map u-boot.map -o u-boot
 endif
 
+ifeq ($(CONFIG_INIT_FUNC),y)
+INIT_SEQ = $(obj)init_seq.o
+
+GEN_UBOOT_INIT = \
+               UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
+               sed  -n -e 
's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
+               cd $(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $$UNDEF_SYM 
$(__OBJS) \
+                       --start-group $(__LIBS) --end-group \
+                       -Map u-boot-init.map -o u-boot-init
+
+$(obj)u-boot-init.lds: $(LDSCRIPT)
+               $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ 
-DMAKE_INIT_LDS -P - <$^ >$@
+
+$(obj)u-boot-init:     depend \
+               $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) 
$(obj)u-boot-init.lds
+               $(GEN_UBOOT_INIT)
+
+$(obj)u-boot-init.bin: $(obj)u-boot-init
+               $(OBJCOPY) -j .initfuncs -O binary $< $@
+
+$(obj)init_seq.c:      depend \
+               $(obj)u-boot-init.bin
+               $(obj)tools/mkinitseq $(obj)u-boot-init.bin 
$(obj)common/init_seq.c
+
+$(obj)init_seq.o:      depend \
+               $(obj)init_seq.c
+               $(MAKE) BUILD_INIT_SEQ=y -C common all
+else
+INIT_SEQ =
+endif
+
 $(obj)u-boot:  depend \
-               $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) 
$(obj)u-boot.lds
+               $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) \
+               $(INIT_SEQ) $(obj)u-boot.lds
                $(GEN_UBOOT)
 ifeq ($(CONFIG_KALLSYMS),y)
                smap=`$(call SYSTEM_MAP,u-boot) | \
diff --git a/common/Makefile b/common/Makefile
index d9f10f3..02a4485 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -195,6 +195,8 @@ COBJS-y += dlmalloc.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
 
+# initialisation sequence (second build stage)
+COBJS-$(BUILD_INIT_SEQ) += init_seq.o
 
 COBJS  := $(sort $(COBJS-y))
 XCOBJS := $(sort $(XCOBJS-y))
diff --git a/config.mk b/config.mk
index fa33e62..2124b84 100644
--- a/config.mk
+++ b/config.mk
@@ -257,6 +257,8 @@ ifneq ($(CONFIG_SYS_TEXT_BASE),)
 LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
 endif
 
+LDFLAGS_u-boot-init += -T $(obj)u-boot-init.lds $(LDFLAGS_FINAL)
+
 LDFLAGS_u-boot-spl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)
 ifneq ($(CONFIG_SPL_TEXT_BASE),)
 LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)
diff --git a/doc/README.INIT_FUNC b/doc/README.INIT_FUNC
new file mode 100644
index 0000000..f9a0b18
--- /dev/null
+++ b/doc/README.INIT_FUNC
@@ -0,0 +1,65 @@
+The INIT_FUNC macro allows initialisation functions (i.e. functions which are
+executed before the main loop) to be easily added to the init sequence
+
+
+Specifying an Initialisation Function and is Dependencies
+---------------------------------------------------------
+The format of the INIT_FUNC macro is:
+
+INIT_FUNC(fn, grp, man_reqs, pre_reqs, pst_reqs)
+
+fn is the name of the init function to call. This function must have the
+following prototype:
+
+int foo(void);
+
+Each init function must return 0 to indicate success - any other return value
+indicates failure and the init sequence will stop
+
+grp is the name of the group that the init function belongs to. grp may be
+the same as fn for any individual init function, but between init functions,
+fn and grp must be unique.
+
+The purpose of groups is to allow functions to be grouped together so other
+functions can specify the group as a whole as a dependency rather than having
+to list every function in the group in the dependency list
+
+man_reqs is a space seperated list of functions or groups that MUST exist and
+MUST run BEFORE fn
+
+pre_reqs is a space seperated list of functions or groups that MAY exist and
+(if they do) MUST run BEFORE fn
+
+pst_reqs is a space seperated list of functions or groups that MAY exist and
+(if they do) MUST run AFTER fn
+
+Skipping or Replacing a Function or Group
+-----------------------------------------
+Occassionally, a board may provide a completely seperate implementation for
+an initialisation function that is provided in the common arch, SoC or
+common code.
+
+SKIP_INIT(fn_or_group)
+
+After the initialisation function dependencies are calculated, all functions
+and groups listed in any SKIP_INITs are removed - This may result in
+dependent functions being removed - It is up to the board code developer
+to ensure suitable replacements are in place
+
+REPLACE_INIT(old_fn_or_group, new_fn_or_group)
+
+Like SKIP_INIT but replaces on function with another (or one group with
+another)
+
+Example: In the SoC code yoy may have
+
+INIT_FUNC(init_cpu_f, RESET, , , );
+
+In the board code, you may want a slightly tweaked version, so you might
+have:
+
+int my_new_init_cpu_f(void)
+{
+       ...
+}
+REPLACE_INIT(init_cpu_f, my_new_init_cpu_f);
diff --git a/include/init_func.h b/include/init_func.h
new file mode 100644
index 0000000..e4366b8
--- /dev/null
+++ b/include/init_func.h
@@ -0,0 +1,37 @@
+#ifndef __INIT_FUNC_H__
+#define __INIT_FUNC_H__
+
+/*
+ * The requirements for any new initalization function is simple: it is
+ * a function with no parameters which returns an integer return code,
+ * where 0 means "continue" and != 0 means "fatal error, hang the system"
+ */
+typedef int (init_fnc_t) (void);
+
+extern init_fnc_t *init_sequence_f[];
+extern init_fnc_t *init_sequence_f_r[];
+extern init_fnc_t *init_sequence_r[];
+
+#ifdef CONFIG_INIT_FUNC
+#include <linux/compiler.h>
+
+#define INIT_FUNC(fn, grp, man_reqs, pre_reqs, pst_reqs) \
+       static const char __init_func_ ## fn[] __used \
+       __attribute__((__section__(".initfuncs"))) = \
+       "(f:" #fn ":" #grp ":" #man_reqs " | " #pre_reqs " | " #pst_reqs ")\n";
+
+#define SKIP_INIT(fn_or_group) \
+       static const char __skip_init_ ## fn_or_group[] __used \
+       __attribute__((__section__(".initfuncs"))) = \
+       "(s:" #fn_or_group ")\n";
+
+#define REPLACE_INIT(old_fn_or_group, new_fn_or_group) \
+       static const char __replace_init_ ## old_fn_or_group[] __used \
+       __attribute__((__section__(".initfuncs"))) = \
+       "(r:" #old_fn_or_group ":" #new_fn_or_group ")\n";
+#else
+#define INIT_FUNC(fn, group, man_reqs, pre_reqs, post_reqs)
+#define SKIP_INIT(fn_or_group)
+#define REPLACE_INIT(old_fn_or_group, new_fn_or_group)
+#endif
+#endif /* !__INIT_FUNC_H__ */
diff --git a/tools/Makefile b/tools/Makefile
index 8993fdd..e6ba6ef 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -68,6 +68,7 @@ BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
 BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
 BIN_FILES-y += mkenvimage$(SFX)
 BIN_FILES-y += mkimage$(SFX)
+BIN_FILES-$(CONFIG_INIT_FUNC) += mkinitseq$(SFX)
 BIN_FILES-$(CONFIG_SMDK5250) += mksmdk5250spl$(SFX)
 BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX)
 BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX)
@@ -95,6 +96,7 @@ NOPED_OBJ_FILES-y += imximage.o
 NOPED_OBJ_FILES-y += omapimage.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
+NOPED_OBJ_FILES-$(CONFIG_INIT_FUNC) += mkinitseq.o
 OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
 OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
 OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
@@ -215,6 +217,10 @@ $(obj)mkimage$(SFX):       $(obj)aisimage.o \
        $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
        $(HOSTSTRIP) $@
 
+$(obj)mkinitseq$(SFX): $(obj)mkinitseq.o
+       $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+       $(HOSTSTRIP) $@
+
 $(obj)mk$(BOARD)spl$(SFX):     $(obj)mkexynosspl.o
        $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
        $(HOSTSTRIP) $@
diff --git a/tools/mkinitseq.c b/tools/mkinitseq.c
new file mode 100644
index 0000000..b150de4
--- /dev/null
+++ b/tools/mkinitseq.c
@@ -0,0 +1,1512 @@
+/*
+ * (C) Copyright 2012
+ * Graeme Russ <graeme.r...@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:       the pointer to the member.
+ * @type:      the type of the container struct this is embedded in.
+ * @member:    the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                     \
+       const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+       (type *)( (char *)__mptr - offsetof(type,member) );})
+
+#include "os_support.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <linux/list.h>
+#include <malloc.h>
+
+#include <version.h>
+
+struct func_def {
+       struct list_head list;
+       char *name;
+};
+
+struct init_def {
+       struct list_head list;
+
+       char *function;
+       char *group;
+
+       int cyclic_checked;
+
+       struct list_head mandatory_deps;
+       struct list_head pre_deps;
+       struct list_head post_deps;
+};
+
+struct skip_def {
+       struct list_head list;
+       char *name;
+};
+
+struct replace_def {
+       struct list_head list;
+       char *old_name;
+       char *new_name;
+};
+
+
+struct init_group {
+       struct list_head list;
+
+       char *name;
+
+       struct list_head functions;
+};
+
+struct list_head init_defs;
+struct list_head skip_defs;
+struct list_head replace_defs;
+
+struct list_head mandatory_functions;
+struct list_head init_groups;
+
+struct list_head init_sequence;
+
+/* These are the initialisation sequence placeholders */
+static const char default_init_reset[] = "f:RESET:RESET: |  | SDRAM";
+static const char default_init_sdram[] = "f:SDRAM:SDRAM: RESET |  | RELOC";
+static const char default_init_reloc[] = "f:RELOC:RELOC: SDRAM |  | ";
+
+static void free_function_list(struct list_head *function_list)
+{
+       struct func_def *tmp;
+
+       while (!list_empty(function_list)) {
+
+               tmp = list_first_entry(function_list, struct func_def, list);
+
+               free(tmp->name);
+               list_del(&tmp->list);
+       }
+}
+
+static int function_exists(const char *function)
+{
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       list_for_each(init_def_pos , &init_defs) {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (!strcmp(init_def->function, function))
+                       return 1;
+       }
+
+       return 0;
+}
+
+static int check_for_empty_groups(void)
+{
+       int err = 0;
+       struct list_head *group_pos;
+       struct init_group *init_group;
+
+       /* Look for an existing group */
+       list_for_each(group_pos, &init_groups)
+       {
+               init_group = list_entry(group_pos, struct init_group, list);
+
+               if (list_empty(&init_group->functions)) {
+                       fprintf(stderr,
+                               "Empty init group '%s'\n",
+                               init_group->name);
+                       err = 1;
+               }
+       }
+
+       return err;
+}
+
+static struct init_def *pop_first_independent_function(void)
+{
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (list_empty(&init_def->pre_deps)) {
+                       list_del(init_def_pos);
+                       return init_def;
+               }
+       }
+
+       return NULL;
+}
+
+static int find_or_create_group(const char *group,
+                               struct init_group **init_group)
+{
+       struct list_head *group_pos;
+
+       /* Look for an existing group */
+       list_for_each(group_pos, &init_groups)
+       {
+               *init_group = list_entry(group_pos, struct init_group, list);
+
+               if (!strcmp((*init_group)->name, group))
+                       return 0;
+       }
+
+       /* No existing group found - Create a new group */
+       *init_group = malloc(sizeof(struct init_group));
+
+       if (!(*init_group))
+               return -ENOMEM;
+
+       (*init_group)->name = strdup(group);
+
+       if (!(*init_group)->name) {
+               free(*init_group);
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&(*init_group)->functions);
+       list_add(&(*init_group)->list, &init_groups);
+
+       return 0;
+}
+
+static int add_function_to_group(const char *function,
+                                const char *group)
+{
+       int err;
+       struct init_group *init_group;
+       struct func_def *func_def;
+
+       if (!strcmp(group, ""))
+               return 0;
+
+       err = find_or_create_group(group, &init_group);
+       if (err)
+               return err;
+
+       /* Add the function to the group */
+       func_def = malloc(sizeof(struct func_def));
+
+       if (!func_def)
+               return -ENOMEM;
+
+       func_def->name = strdup(function);
+
+       if (!func_def->name) {
+               free(func_def);
+               return -ENOMEM;
+       }
+
+       list_add(&func_def->list, &init_group->functions);
+
+       return 0;
+}
+
+static void delete_group(const char *group)
+{
+       struct list_head *init_group_pos;
+       struct list_head *q;
+       struct init_group *init_group;
+
+
+       list_for_each_safe(init_group_pos, q, &init_groups) {
+               init_group = list_entry(init_group_pos,
+                                       struct init_group,
+                                       list);
+
+               if (!strcmp(init_group->name, group)) {
+                       free(init_group->name);
+                       free_function_list(&init_group->functions);
+
+                       list_del(init_group_pos);
+
+                       free(init_group);
+               }
+       }
+
+}
+
+static void delete_dep_from_init_defs(const char *dep)
+{
+       struct list_head *init_def_pos;
+       struct list_head *func_def_pos;
+       struct init_def *init_def;
+       struct func_def *func_def;
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               init_def = list_entry(init_def_pos,
+                                     struct init_def,
+                                     list);
+
+               list_for_each(func_def_pos , &init_def->pre_deps)
+               {
+                       func_def = list_entry(func_def_pos,
+                                             struct func_def,
+                                             list);
+
+                       if (!strcmp(func_def->name, dep)) {
+                               free(func_def->name);
+                               list_del(func_def_pos);
+                               free(func_def);
+                               break;
+                       }
+               }
+
+       }
+}
+
+
+static int add_mandatory_function(const char *name)
+{
+       struct list_head *position;
+       struct func_def *func_def;
+
+       list_for_each(position, &mandatory_functions)
+       {
+               func_def = list_entry(position, struct func_def, list);
+
+               if (!strcmp(func_def->name, name))
+                       return 0;
+       }
+
+       func_def = malloc(sizeof(struct func_def));
+
+       if (!func_def)
+               return -ENOMEM;
+
+       func_def->name = strdup(name);
+
+       if (!func_def->name) {
+               free(func_def);
+               return -ENOMEM;
+       }
+
+       list_add(&func_def->list, &mandatory_functions);
+
+       return 0;
+}
+
+static int process_dep_list(struct list_head *dep_list,
+                           char *deps,
+                           int mandatory)
+{
+       int err = 0;
+       struct func_def *func_def;
+       char *save_ptr;
+
+       char *dep_function;
+
+       dep_function = strtok_r(deps, " \t", &save_ptr);
+
+       while (dep_function) {
+               func_def = malloc(sizeof(struct func_def));
+
+               if (!func_def)
+                       return -ENOMEM;
+
+               func_def->name = strdup(dep_function);
+
+               if (!func_def->name) {
+                       free(func_def);
+                       return -ENOMEM;
+               }
+
+               list_add(&func_def->list, dep_list);
+
+               if (mandatory)
+                       if (add_mandatory_function(dep_function))
+                               err = 1;
+
+               dep_function = strtok_r(NULL, " ", &save_ptr);
+       };
+
+       return err;
+}
+
+static int process_init_info(struct init_def *init_def,
+                            char *deps)
+{
+       char *mandatory_deps;
+       char *pre_deps;
+       char *post_deps;
+       char *save_ptr;
+
+       INIT_LIST_HEAD(&init_def->mandatory_deps);
+       INIT_LIST_HEAD(&init_def->pre_deps);
+       INIT_LIST_HEAD(&init_def->post_deps);
+
+       mandatory_deps = strtok_r(deps, "|", &save_ptr);
+       pre_deps = strtok_r(NULL, "|", &save_ptr);
+       post_deps = strtok_r(NULL, "|", &save_ptr);
+
+       process_dep_list(&init_def->mandatory_deps, mandatory_deps, 1);
+       process_dep_list(&init_def->pre_deps, pre_deps, 0);
+       process_dep_list(&init_def->post_deps, post_deps, 0);
+
+       return 0;
+}
+
+static int check_for_duplicates(const char *function,
+                               const char *group)
+{
+       struct list_head *position;
+       struct init_def *init_def;
+
+       list_for_each(position , &init_defs)
+       {
+               init_def = list_entry(position, struct init_def, list);
+
+               if (!strcmp(function, init_def->function)) {
+                       fprintf(stderr,
+                               "Duplicate function name '%s'\n",
+                               function);
+
+                       return -EEXIST;
+               }
+
+               if (!strcmp(function, init_def->group)) {
+                       fprintf(stderr,
+                               "Function '%s' matches an existing group\n",
+                               function);
+
+                       return -EEXIST;
+               }
+
+               if (!strcmp(group, init_def->function)) {
+                       fprintf(stderr,
+                               "Group '%s' matches an existing function\n",
+                               function);
+
+                       return -EEXIST;
+               }
+       }
+
+       return 0;
+}
+
+static int add_to_init_list(const char *function,
+                           const char *group,
+                           char *deps)
+{
+       int err;
+       struct init_def *init_def;
+
+       /* Check that the function is not already included */
+       err = check_for_duplicates(function, group);
+
+       if (err)
+               return err;
+
+       /* Create a list node for the new init function */
+       init_def = malloc(sizeof(struct init_def));
+
+       if (!init_def)
+               return -ENOMEM;
+
+       init_def->function = strdup(function);
+       init_def->group = strdup(group);
+       init_def->cyclic_checked = 0;
+
+       if ((!init_def->function) ||
+           (!init_def->group)) {
+               free(init_def->function);
+               free(init_def->group);
+               free(init_def);
+               return -ENOMEM;
+       }
+
+       /* Add the new function to the init function list */
+       list_add(&init_def->list, &init_defs);
+
+       /* Process the new functions dependencies */
+       err = process_init_info(init_def, deps);
+
+       if (err)
+               return err;
+
+       return add_function_to_group(function, group);
+}
+
+static int add_to_skip_list(const char *function_name)
+{
+       struct list_head *skip_pos;
+       struct list_head *replace_pos;
+
+       struct skip_def *skip_def = NULL;
+       struct replace_def *rdef;
+
+       /* Duplicate skip definitions are OK, but we only need the fist one */
+       list_for_each(skip_pos, &skip_defs)
+       {
+               skip_def = list_entry(skip_pos, struct skip_def, list);
+
+               if (!strcmp(function_name, skip_def->name))
+                       return 0;
+       }
+
+       /* Skip definitions matching a replace definition are not OK */
+       list_for_each(replace_pos, &replace_defs)
+       {
+               rdef = list_entry(replace_pos,
+                                 struct replace_def,
+                                 list);
+
+               if (!strcmp(skip_def->name, rdef->old_name) ||
+                   !strcmp(skip_def->name, rdef->new_name)) {
+                       fprintf(stderr,
+                               "Skip '%s' is in a replace definition\n",
+                               skip_def->name);
+                       return -EEXIST;
+               }
+       }
+
+       skip_def = malloc(sizeof(struct skip_def));
+
+       if (!skip_def)
+               return -ENOMEM;
+
+       skip_def->name = strdup(function_name);
+
+       if (!skip_def->name) {
+               free(skip_def);
+               return -ENOMEM;
+       }
+
+       list_add(&skip_def->list, &skip_defs);
+
+       return 0;
+}
+
+static int add_to_replace_list(const char *old_name, const char *new_name)
+{
+       struct list_head *skip_pos;
+       struct list_head *replace_pos;
+
+       struct skip_def *skip_def;
+       struct replace_def *rdef;
+
+       /* Duplicate replace definitions are not OK */
+       list_for_each(replace_pos , &replace_defs)
+       {
+               rdef = list_entry(replace_pos,
+                                 struct replace_def,
+                                 list);
+
+               if (!strcmp(old_name, rdef->old_name) ||
+                   !strcmp(old_name, rdef->new_name)) {
+                       fprintf(stderr,
+                               "Multiple replace defs for function '%s'\n",
+                               old_name);
+
+                       return -EEXIST;
+               }
+
+               if (!strcmp(new_name, rdef->old_name) ||
+                   !strcmp(new_name, rdef->new_name)) {
+                       fprintf(stderr,
+                               "Multiple replace defs for function '%s'\n",
+                               new_name);
+
+                       return -EEXIST;
+               }
+       }
+
+       /* Replace definitions matching a skip definition are not OK */
+       list_for_each(skip_pos, &skip_defs)
+       {
+               skip_def = list_entry(skip_pos, struct skip_def, list);
+
+               if (!strcmp(skip_def->name, old_name)) {
+                       fprintf(stderr,
+                               "Replace '%s' is in a skip definition\n",
+                               old_name);
+                       return -EEXIST;
+               }
+
+               if (!strcmp(skip_def->name, new_name)) {
+                       fprintf(stderr,
+                               "Replace '%s' is in a skip definition\n",
+                               new_name);
+                       return -EEXIST;
+               }
+       }
+
+       rdef = malloc(sizeof(struct replace_def));
+
+       if (!rdef)
+               return -ENOMEM;
+
+       rdef->old_name = strdup(old_name);
+       rdef->new_name = strdup(new_name);
+
+       if ((!rdef->old_name) || (!rdef->new_name)) {
+               free(rdef->old_name);
+               free(rdef->new_name);
+               free(rdef);
+               return -ENOMEM;
+       }
+
+       list_add(&rdef->list, &replace_defs);
+
+       return 0;
+}
+
+static int process_initcall_string(const char *string)
+{
+       char *save_ptr;
+       char *def_type;
+       char *function;
+       char *group;
+       char *old_name;
+       char *new_name;
+       char *deps;
+       int err;
+
+       char *local_string = strdup(string);
+
+       if (!local_string)
+               return -ENOMEM;
+
+       def_type = strtok_r(local_string, ":", &save_ptr);
+
+       switch (def_type[0]) {
+       case 'f':
+               /* An init function definition - Get the function name */
+               function = strtok_r(NULL, ":", &save_ptr);
+               group = strtok_r(NULL, ":", &save_ptr);
+               deps = strtok_r(NULL, ":", &save_ptr);
+
+               err = add_to_init_list(function, group, deps);
+               break;
+
+       case 's':
+               function = strtok_r(NULL, ":", &save_ptr);
+
+               err = add_to_skip_list(function);
+               break;
+
+       case 'r':
+               old_name = strtok_r(NULL, ":", &save_ptr);
+               new_name = strtok_r(NULL, ":", &save_ptr);
+
+               err = add_to_replace_list(old_name, new_name);
+               break;
+
+       default:
+               fprintf(stderr, "Unknown Init Type: %s", def_type);
+               err = -ENOENT;
+               break;
+       }
+
+       free(local_string);
+       return err;
+}
+
+static int process_marker_strings(void)
+{
+       int err = 0;
+
+       err = process_initcall_string(default_init_reset);
+       if (err)
+               return err;
+
+       err = process_initcall_string(default_init_sdram);
+       if (err)
+               return err;
+
+       err = process_initcall_string(default_init_reloc);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int build_function_list(char *buffer)
+{
+       int err = 0;
+
+       char *save_ptr;
+
+       char *init_call_string;
+
+       err = process_marker_strings();
+       if (err)
+               return err;
+
+       init_call_string = strtok_r(buffer, "()", &save_ptr);
+
+       while (init_call_string) {
+               if (process_initcall_string(init_call_string))
+                       err = 1;
+
+               /* Skip the garbage between init definitions */
+               init_call_string = strtok_r(NULL, "(", &save_ptr);
+
+               /* Get the next init definition */
+               init_call_string = strtok_r(NULL, ")", &save_ptr);
+       };
+
+       return err;
+}
+
+static int open_file(const char *file, char **buffer, int *buf_size)
+{
+       struct stat sbuf;
+       int file_ptr;
+
+       char *ptr;
+
+       file_ptr = open(file, O_RDONLY|O_BINARY);
+
+       if (file_ptr < 0) {
+               fprintf(stderr, "Can't open %s: %s\n", file, strerror(errno));
+               return errno;
+       }
+
+       if (fstat(file_ptr, &sbuf) < 0) {
+               fprintf(stderr, "Can't stat %s: %s\n", file, strerror(errno));
+               return errno;
+       }
+
+       ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, file_ptr, 0);
+       if (ptr == MAP_FAILED) {
+               fprintf(stderr, "Can't read %s: %s\n", file, strerror(errno));
+               return errno;
+       }
+
+       *buffer = malloc(sbuf.st_size + 1);
+
+       if (!*buffer)
+               return -ENOMEM;
+
+       *buf_size = sbuf.st_size;
+       memcpy(*buffer, ptr, sbuf.st_size);
+       (*buffer)[sbuf.st_size] = 0x00;
+
+       munmap((void *)ptr, sbuf.st_size);
+       close(file_ptr);
+
+       return 0;
+}
+
+static int check_mandatory_list(void)
+{
+       int err = 0;
+       struct list_head *position;
+       struct list_head *q;
+       struct list_head *sub_position;
+       struct init_def *init_def;
+       struct func_def *func_def;
+
+
+       /* Remove functions that exist from the mandatory functions list */
+       list_for_each_safe(position, q, &mandatory_functions) {
+               func_def = list_entry(position, struct func_def, list);
+
+               list_for_each(sub_position , &init_defs) {
+                       init_def = list_entry(sub_position,
+                                             struct init_def,
+                                             list);
+
+                       if (!strcmp(func_def->name, init_def->function) ||
+                           !strcmp(func_def->name, init_def->group)) {
+                               free(func_def->name);
+
+                               list_del(position);
+                               free(func_def);
+                       }
+               }
+
+       }
+
+       list_for_each(position , &mandatory_functions) {
+               func_def = list_entry(position, struct func_def, list);
+
+               fprintf(stderr,
+                       "Missing mandatory function: %s\n",
+                       func_def->name);
+               err = 1;
+       }
+
+       return err;
+}
+
+static int process_skip_list(void)
+{
+       int err = 0;
+       int group_skip = 0;
+
+       /*
+        * The same function cannot appear in both the skip list and the
+        * replace list (either as the new or old function name)
+        */
+       struct list_head *skip_pos;
+       struct skip_def *skip_def;
+
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       struct list_head *q;
+
+       list_for_each(skip_pos, &skip_defs)
+       {
+               skip_def = list_entry(skip_pos, struct skip_def, list);
+
+               /* Remove the named skip from init entries */
+               list_for_each_safe(init_def_pos, q, &init_defs) {
+                       init_def = list_entry(init_def_pos,
+                                             struct init_def,
+                                             list);
+                       /*
+                        * We already know that function and group names
+                        * are unique across both namespaces so we can
+                        * delete any init definitions whose function or
+                        * group name matches the skip name
+                        */
+                       if (!strcmp(init_def->group, skip_def->name))
+                               group_skip = 1;
+
+                       if (!strcmp(init_def->function, skip_def->name) ||
+                           group_skip) {
+                               free(init_def->function);
+                               free(init_def->group);
+
+                               free_function_list(&init_def->mandatory_deps);
+                               free_function_list(&init_def->post_deps);
+                               free_function_list(&init_def->pre_deps);
+
+                               list_del(init_def_pos);
+
+                               free(init_def);
+                       }
+               }
+
+               if (group_skip)
+                       /* Remove the named skip group */
+                       delete_group(skip_def->name);
+       }
+
+       return err;
+}
+
+static int process_replace_list(void)
+{
+       int err = 0;
+
+       struct list_head *init_def_pos;
+       struct list_head *replace_pos;
+
+       struct init_def *init_def;
+       struct replace_def *rdef;
+
+       struct init_group *dummy;
+
+       int group_replace;
+       int function_replace;
+
+       list_for_each(replace_pos, &replace_defs)
+       {
+               rdef = list_entry(replace_pos, struct replace_def, list);
+
+               group_replace = 0;
+               function_replace = 0;
+
+               list_for_each(init_def_pos , &init_defs)
+               {
+                       init_def = list_entry(init_def_pos,
+                                             struct init_def,
+                                             list);
+
+                       if (!strcmp(init_def->function,
+                                   rdef->old_name)) {
+                               /* Function replacements are easy */
+                               function_replace = 1;
+
+                               free(init_def->function);
+                               init_def->function = strdup(rdef->new_name);
+
+                               if (!init_def->function)
+                                       return -ENOMEM;
+
+                       } else if (!strcmp(init_def->group,
+                                   rdef->old_name)) {
+                               /* Hmm, a group replacement */
+                               group_replace = 1;
+
+                               free(init_def->group);
+                               init_def->group = strdup(rdef->new_name);
+
+                               if (!init_def->group)
+                                       return -ENOMEM;
+                       }
+               }
+
+               if (group_replace) {
+                       /* Delete 'old name' group */
+                       delete_group(rdef->old_name);
+
+                       /*
+                        * Create a 'new group' (if it does not already
+                        * exist. It will be tested later and if it is
+                        * empty, an error will be reported
+                        */
+                       err = find_or_create_group(rdef->new_name, &dummy);
+                       if (!err)
+                               return err;
+               }
+
+               if (!group_replace && !function_replace) {
+                       fprintf(stderr,
+                               "Replace function %s not in init list\n",
+                               rdef->old_name);
+                       err = ENOENT;
+               }
+       }
+
+       return err;
+}
+
+static int add_dep(const char *function, const char *dep)
+{
+       int found = 0;
+
+       struct list_head *init_def_pos;
+       struct list_head *pre_dep_pos;
+
+       struct init_def *init_def;
+       struct func_def *func_def;
+       struct func_def *pre_dep_id;
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (!strcmp(init_def->function, function)) {
+
+                       list_for_each(pre_dep_pos, &init_def->pre_deps) {
+                               pre_dep_id = list_entry(pre_dep_pos,
+                                                       struct func_def,
+                                                       list);
+                               if (!strcmp(pre_dep_id->name, dep)) {
+                                       found = 1;
+                                       break;
+                               }
+
+                       }
+
+                       if (!found) {
+                               func_def = malloc(sizeof(struct func_def));
+
+                               if (!func_def)
+                                       return -ENOMEM;
+
+                               func_def->name = strdup(dep);
+
+                               if (!func_def->name) {
+                                       free(func_def);
+                                       return -ENOMEM;
+                               }
+
+                               list_add(&func_def->list, &init_def->pre_deps);
+                       }
+
+                       return 0;
+               }
+       }
+
+       fprintf(stderr, "Function '%s' not found\n", function);
+       return -ENOENT;
+}
+
+
+static int insert_into_dep_list(struct list_head *dep_list,
+                               struct init_group *init_group)
+{
+       struct list_head *position;
+       struct func_def *func_def;
+       struct func_def *new_func_def;
+
+       list_for_each(position, &init_group->functions)
+       {
+               func_def = list_entry(position, struct func_def, list);
+
+               new_func_def = malloc(sizeof(struct func_def));
+
+               if (!new_func_def)
+                       return -ENOMEM;
+
+               new_func_def->name = strdup(func_def->name);
+
+               if (!new_func_def->name) {
+                       free(new_func_def);
+                       return -ENOMEM;
+               }
+
+               list_add(&new_func_def->list, dep_list);
+       }
+
+       return 0;
+}
+
+static int expand_dep_list(struct list_head *dep_list)
+{
+       int err = 0;
+
+       struct list_head *position;
+       struct func_def *func_def;
+       struct list_head *q;
+
+       struct list_head *step_pos;
+       struct init_group *init_group;
+
+
+       list_for_each_safe(position, q, dep_list) {
+               func_def = list_entry(position, struct func_def, list);
+
+               /* Is this a 'step' rather than a 'function' */
+               list_for_each(step_pos, &init_groups)
+               {
+                       init_group = list_entry(step_pos,
+                                               struct init_group,
+                                               list);
+
+                       if (!strcmp(init_group->name, func_def->name)) {
+                               /*
+                                * Replace this init id (which is a 'step'
+                                * with the list of step functions
+                                */
+                               free(func_def->name);
+
+                               list_del(position);
+                               free(func_def);
+
+                               err = insert_into_dep_list(dep_list,
+                                                          init_group);
+
+                               if (err)
+                                       return err;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int expand_dep_lists(void)
+{
+       int err = 0;
+
+       struct list_head *position;
+       struct init_def *init_def;
+
+       list_for_each(position , &init_defs)
+       {
+               init_def = list_entry(position, struct init_def, list);
+
+               err = expand_dep_list(&init_def->mandatory_deps);
+
+               if (err)
+                       return err;
+
+               err = expand_dep_list(&init_def->pre_deps);
+
+               if (err)
+                       return err;
+
+               err = expand_dep_list(&init_def->post_deps);
+
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+
+static void remove_unused_deps(struct list_head *list,
+                              const char *function,
+                              const char *dep_type)
+{
+       struct list_head *dep_pos;
+       struct func_def *func_def;
+       struct list_head *q;
+
+       list_for_each_safe(dep_pos, q, list)
+       {
+               func_def = list_entry(dep_pos,
+                                    struct func_def,
+                                    list);
+
+               if (!function_exists(func_def->name)) {
+                       fprintf(stderr,
+                               "Removing unmet %s dep '%s' from '%s'\n",
+                               dep_type,
+                               func_def->name,
+                               function);
+                       free(func_def->name);
+                       list_del(dep_pos);
+                       free(func_def);
+               }
+       }
+
+}
+
+static int strip_unmet_deps(void)
+{
+       /*
+        * Any entry in the pre-dep and post-dep lists that do not have a
+        * matching entry in the init_defs list can be removed
+        */
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               remove_unused_deps(&init_def->pre_deps,
+                                  init_def->function,
+                                  "pre");
+               remove_unused_deps(&init_def->post_deps,
+                                  init_def->function,
+                                  "post");
+       }
+
+       return 0;
+}
+
+static int cleanup_dep_lists(void)
+{
+       int err = 0;
+       int found;
+
+       struct list_head *init_def_pos;
+       struct list_head *dep_pos;
+       struct list_head *pre_dep_pos;
+
+       struct list_head *q;
+
+       struct init_def *init_def;
+       struct func_def *func_def;
+       struct func_def *pre_dep_id;
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               /* Convert post-deps into pre-deps */
+               list_for_each_safe(dep_pos, q, &init_def->post_deps)
+               {
+                       func_def = list_entry(dep_pos,
+                                             struct func_def,
+                                             list);
+
+                       err = add_dep(func_def->name, init_def->function);
+                       if (err)
+                               return err;
+
+                       list_del(dep_pos);
+
+                       free(func_def->name);
+                       free(func_def);
+               }
+
+               /* Move mandatory deps into pre-deps list */
+               list_for_each_safe(dep_pos, q, &init_def->mandatory_deps)
+               {
+                       func_def = list_entry(dep_pos,
+                                             struct func_def,
+                                             list);
+
+                       list_del(dep_pos);
+
+                       found = 0;
+
+                       list_for_each(pre_dep_pos, &init_def->pre_deps)
+                       {
+                               pre_dep_id = list_entry(pre_dep_pos,
+                                                       struct func_def,
+                                                       list);
+
+                               if (!strcmp(func_def->name, pre_dep_id->name)) {
+                                       found = 1;
+                                       break;
+                               }
+
+                       }
+
+                       if (!found) {
+                               list_add(&func_def->list,
+                                        &init_def->pre_deps);
+                       } else {
+                               free(func_def->name);
+                               free(func_def);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int check_unique_root_function(void)
+{
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       int root_functions = 0;
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (list_empty(&init_def->pre_deps))
+                       root_functions++;
+       }
+
+       if (root_functions != 1)
+               return -EINVAL;
+       else
+               return 0;
+}
+
+static void dump_dep_stack(struct list_head *dep_stack, const char *function)
+{
+       struct list_head *func_def_pos;
+       struct func_def *func_def;
+
+       list_for_each(func_def_pos , dep_stack) {
+               func_def = list_entry(func_def_pos, struct func_def, list);
+
+               fprintf(stderr, "  %s\n", func_def->name);
+
+               if (!strcmp(func_def->name, function))
+                       return;
+       }
+}
+
+static struct init_def *find_init_def_by_function(const char *function)
+{
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (!strcmp(init_def->function, function))
+                       return init_def;
+       }
+
+       fprintf(stderr, "Cannot find %s\n", function);
+
+       return NULL;
+}
+
+static int check_init_def_cyclic(struct init_def *init_def,
+                                struct list_head *dep_stack)
+{
+       int err = 0;
+
+       struct list_head *func_def_pos;
+       struct func_def *func_def;
+
+       struct list_head *dep_init_func_pos;
+       struct func_def *dep_init_func;
+       struct init_def *dep_init_def;
+
+       if (init_def->cyclic_checked)
+               return 0;
+
+       /* Check if this function already in the dependency stack */
+       list_for_each(func_def_pos , dep_stack) {
+               func_def = list_entry(func_def_pos, struct func_def, list);
+
+               if (!strcmp(init_def->function, func_def->name)) {
+                       fprintf(stderr,
+                               "Function '%s' has cyclic dependency\n",
+                               init_def->function);
+
+                       /* Dump the dependency stack */
+                       dump_dep_stack(dep_stack, init_def->function);
+
+                       init_def->cyclic_checked = 1;
+                       return -EEXIST;
+               }
+       }
+
+       /* Add this function to the check stack */
+       func_def = malloc(sizeof(struct func_def));
+
+       if (!func_def)
+               return -ENOMEM;
+
+       func_def->name = strdup(init_def->function);
+
+       if (!func_def->name) {
+               free(func_def);
+               return -ENOMEM;
+       }
+
+       list_add(&func_def->list, dep_stack);
+
+       /* Now check the all the dependencies of this function */
+       list_for_each(dep_init_func_pos , &init_def->pre_deps)
+       {
+               dep_init_func = list_entry(dep_init_func_pos,
+                                          struct func_def,
+                                          list);
+
+               dep_init_def = find_init_def_by_function(dep_init_func->name);
+
+               if (!dep_init_def)
+                       return 1;
+
+               if (check_init_def_cyclic(dep_init_def, dep_stack))
+                       err = 1;
+       }
+
+       init_def->cyclic_checked = 1;
+
+       return err;
+}
+
+static void clear_dep_stack(struct list_head *dep_stack)
+{
+       struct list_head *func_def_pos;
+       struct list_head *q;
+       struct func_def *func_def;
+
+       list_for_each_safe(func_def_pos, q, dep_stack) {
+               func_def = list_entry(func_def_pos,
+                                     struct func_def,
+                                     list);
+
+               list_del(func_def_pos);
+               free(func_def->name);
+               free(func_def);
+       }
+}
+
+static int check_for_cyclic_deps(void)
+{
+       int err = 0;
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       struct list_head dep_stack;
+
+
+       INIT_LIST_HEAD(&dep_stack);
+
+       list_for_each(init_def_pos , &init_defs)
+       {
+               clear_dep_stack(&dep_stack);
+
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (!init_def->cyclic_checked)
+                       if (check_init_def_cyclic(init_def, &dep_stack))
+                               err = 1;
+       }
+
+       clear_dep_stack(&dep_stack);
+
+       return err;
+}
+
+int generate_init_sequence(void)
+{
+       struct init_def *init_def;
+
+       while (!list_empty(&init_defs)) {
+               init_def = pop_first_independent_function();
+
+               if (!init_def) {
+                       fprintf(stderr, "Cyclic deps\n");
+                       return 0;
+               }
+
+               list_add_tail(&init_def->list, &init_sequence);
+
+               delete_dep_from_init_defs(init_def->function);
+       }
+
+       return 0;
+}
+
+int generate_c_file(const char *file)
+{
+       struct list_head *init_def_pos;
+       struct init_def *init_def;
+
+       FILE *file_ptr = fopen(file, "w");
+
+       if (!file_ptr) {
+               fprintf(stderr, "Can't open %s: %s\n", file, strerror(errno));
+               return errno;
+       }
+
+       fputs("/*\n", file_ptr);
+       fputs(" * DO NOT MODIFY.\n", file_ptr);
+       fputs(" *\n", file_ptr);
+       fputs(" * This file was generated by mkinitseq\n", file_ptr);
+       fputs(" *\n", file_ptr);
+       fputs(" */\n", file_ptr);
+       fputs("\n", file_ptr);
+       fputs("#include <init_func.h>\n", file_ptr);
+       fputs("#include <linux/stddef.h>\n", file_ptr);
+       fputs("\n", file_ptr);
+
+       list_for_each(init_def_pos , &init_sequence)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (strcmp(init_def->function, "RESET") &
+                   strcmp(init_def->function, "SDRAM") &
+                   strcmp(init_def->function, "RELOC")) {
+                       fprintf(file_ptr, "int %s(void);\n",
+                               init_def->function);
+               }
+       }
+
+       list_for_each(init_def_pos , &init_sequence)
+       {
+               init_def = list_entry(init_def_pos, struct init_def, list);
+
+               if (!strcmp(init_def->function, "RESET")) {
+                       fputs("init_fnc_t *init_sequence_f[] = {\n",
+                             file_ptr);
+               } else if (!strcmp(init_def->function, "SDRAM")) {
+                       fputs("\n", file_ptr);
+                       fputs("\t\tNULL,\n", file_ptr);
+                       fputs("\t};\n", file_ptr);
+
+                       fputs("\n", file_ptr);
+                       fputs("init_fnc_t *init_sequence_f_r[] = {\n",
+                             file_ptr);
+               } else if (!strcmp(init_def->function, "RELOC")) {
+                       fputs("\n", file_ptr);
+                       fputs("\t\tNULL,\n", file_ptr);
+                       fputs("\t};\n", file_ptr);
+
+                       fputs("\n", file_ptr);
+                       fputs("init_fnc_t *init_sequence_r[] = {\n",
+                             file_ptr);
+               } else {
+                       fprintf(file_ptr, "\t\t%s,\n", init_def->function);
+               }
+       }
+
+       fputs("\n", file_ptr);
+       fputs("\t\tNULL,\n", file_ptr);
+       fputs("\t};\n", file_ptr);
+
+       fclose(file_ptr);
+
+       return 0;
+}
+
+void init_lists(void)
+{
+       INIT_LIST_HEAD(&init_defs);
+       INIT_LIST_HEAD(&skip_defs);
+       INIT_LIST_HEAD(&replace_defs);
+
+       INIT_LIST_HEAD(&mandatory_functions);
+       INIT_LIST_HEAD(&init_groups);
+
+       INIT_LIST_HEAD(&init_sequence);
+}
+
+int main(int argc, const char **argv)
+{
+       int err;
+       int buf_size = 0;
+       char *local_buffer = NULL;
+       char *x;
+
+       printf("Generating init sequence from %s\n", argv[1]);
+
+       /* Read the init function definitions into a local buffer */
+       err = open_file(argv[1], &local_buffer, &buf_size);
+
+       if (err || !local_buffer)
+               exit(EXIT_FAILURE);
+
+       /*
+        * Convert all the NULLs (except the last one) to non-NULL so
+        * the buffer can be processed using standard string functions
+        */
+       for (x = local_buffer; x != &local_buffer[buf_size]; x++) {
+               if (*x == 0x00)
+                       *x = 0x01;
+       }
+
+       init_lists();
+
+       if (build_function_list(local_buffer))
+               exit(EXIT_FAILURE);
+
+       if (check_mandatory_list())
+               exit(EXIT_FAILURE);
+
+       if (process_skip_list())
+               exit(EXIT_FAILURE);
+
+       if (process_replace_list())
+               exit(EXIT_FAILURE);
+
+       if (check_for_empty_groups())
+               exit(EXIT_FAILURE);
+
+       if (expand_dep_lists())
+               exit(EXIT_FAILURE);
+
+       if (strip_unmet_deps())
+               exit(EXIT_FAILURE);
+
+       if (cleanup_dep_lists())
+               exit(EXIT_FAILURE);
+
+       if (check_unique_root_function())
+               exit(EXIT_FAILURE);
+
+       if (check_for_cyclic_deps())
+               exit(EXIT_FAILURE);
+
+       if (generate_init_sequence())
+               exit(EXIT_FAILURE);
+
+       if (generate_c_file(argv[2]))
+               exit(EXIT_FAILURE);
+
+       free(local_buffer);
+       exit(EXIT_SUCCESS);
+}
-- 
1.7.7.6

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to