All of lore.kernel.org
 help / color / mirror / Atom feed
From: Graeme Russ <graeme.russ@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/3] init_func: Add fundamental framework
Date: Mon, 23 Apr 2012 01:23:06 +1000	[thread overview]
Message-ID: <1335108188-21875-2-git-send-email-graeme.russ@gmail.com> (raw)
In-Reply-To: <1335108188-21875-1-git-send-email-graeme.russ@gmail.com>


Signed-off-by: Graeme Russ <graeme.russ@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.russ@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

  reply	other threads:[~2012-04-22 15:23 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-22 15:23 [U-Boot] [PATCH 0/3] Initialisation Sequence Framework Graeme Russ
2012-04-22 15:23 ` Graeme Russ [this message]
2012-05-03  0:08   ` [U-Boot] [PATCH 1/3] init_func: Add fundamental framework Marek Vasut
2012-05-03  3:06     ` Graeme Russ
2012-05-03  3:18       ` Marek Vasut
2012-05-03  4:12         ` Graeme Russ
2012-05-03 14:38           ` Marek Vasut
2012-04-22 15:23 ` [U-Boot] [PATCH 2/3] init_func: Add x86 support Graeme Russ
2012-04-22 15:23 ` [U-Boot] [PATCH 3/3] init_func: Use for eNET board Graeme Russ
2012-05-02 23:50 ` [U-Boot] [PATCH 0/3] Initialisation Sequence Framework Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1335108188-21875-2-git-send-email-graeme.russ@gmail.com \
    --to=graeme.russ@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.