Export redesign

this is an atempt to make the export of functions typesafe.
I replaced the jumptable void ** by a struct (jt_funcs) with function pointers.
The EXPORT_FUNC macro now has 3 fixed parameters and one
variadic parameter
The first is the name of the exported function,
the rest of the parameters are used to format a functionpointer
in the jumptable,

the EXPORT_FUNC macros are expanded three times,
1. to declare the members of the struct
2. to initialize the structmember pointers
3. to call the functions in stubs.c

Signed-off-by: Martin Dorwig <dorwig@tetronik.com>
Acked-by: Simon Glass <sjg@chromium.org>

Signed-off-by: Simon Glass <sjg@chromium.org>
(resending to the list since my tweaks are not quite trivial)
diff --git a/include/_exports.h b/include/_exports.h
index 349a3c5..5944703 100644
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -1,32 +1,73 @@
 /*
- * You do not need to use #ifdef around functions that may not exist
+ * You need to use #ifdef around functions that may not exist
  * in the final configuration (such as i2c).
+ * use a dummyfunction as first parameter to EXPORT_FUNC.
+ * As an example see the CONFIG_CMD_I2C section below
  */
-EXPORT_FUNC(get_version)
-EXPORT_FUNC(getc)
-EXPORT_FUNC(tstc)
-EXPORT_FUNC(putc)
-EXPORT_FUNC(puts)
-EXPORT_FUNC(printf)
-EXPORT_FUNC(install_hdlr)
-EXPORT_FUNC(free_hdlr)
-EXPORT_FUNC(malloc)
-EXPORT_FUNC(free)
-EXPORT_FUNC(udelay)
-EXPORT_FUNC(get_timer)
-EXPORT_FUNC(vprintf)
-EXPORT_FUNC(do_reset)
-EXPORT_FUNC(getenv)
-EXPORT_FUNC(setenv)
-EXPORT_FUNC(simple_strtoul)
-EXPORT_FUNC(strict_strtoul)
-EXPORT_FUNC(simple_strtol)
-EXPORT_FUNC(strcmp)
-EXPORT_FUNC(i2c_write)
-EXPORT_FUNC(i2c_read)
-EXPORT_FUNC(spi_init)
-EXPORT_FUNC(spi_setup_slave)
-EXPORT_FUNC(spi_free_slave)
-EXPORT_FUNC(spi_claim_bus)
-EXPORT_FUNC(spi_release_bus)
-EXPORT_FUNC(spi_xfer)
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC(a, b, c, ...)
+#endif
+	EXPORT_FUNC(get_version, unsigned long, get_version, void)
+	EXPORT_FUNC(getc, int, getc, void)
+	EXPORT_FUNC(tstc, int, tstc, void)
+	EXPORT_FUNC(putc, void, putc, const char)
+	EXPORT_FUNC(puts, void, puts, const char *)
+	EXPORT_FUNC(printf, int, printf, const char*, ...)
+#if defined(CONFIG_X86) || defined(CONFIG_PPC)
+	EXPORT_FUNC(irq_install_handler, void, install_hdlr,
+		    int, interrupt_handler_t, void*)
+
+	EXPORT_FUNC(irq_free_handler, void, free_hdlr, int)
+#else
+	EXPORT_FUNC(dummy, void, install_hdlr, void)
+	EXPORT_FUNC(dummy, void, free_hdlr, void)
+#endif
+	EXPORT_FUNC(malloc, void *, malloc, size_t)
+	EXPORT_FUNC(free, void, free, void *)
+	EXPORT_FUNC(udelay, void, udelay, unsigned long)
+	EXPORT_FUNC(get_timer, unsigned long, get_timer, unsigned long)
+	EXPORT_FUNC(vprintf, int, vprintf, const char *, va_list)
+	EXPORT_FUNC(do_reset, int, do_reset, cmd_tbl_t *,
+		    int , int , char * const [])
+	EXPORT_FUNC(getenv, char  *, getenv, const char*)
+	EXPORT_FUNC(setenv, int, setenv, const char *, const char *)
+	EXPORT_FUNC(simple_strtoul, unsigned long, simple_strtoul,
+		    const char *, char **, unsigned int)
+	EXPORT_FUNC(strict_strtoul, int, strict_strtoul,
+		    const char *, unsigned int , unsigned long *)
+	EXPORT_FUNC(simple_strtol, long, simple_strtol,
+		    const char *, char **, unsigned int)
+	EXPORT_FUNC(strcmp, int, strcmp, const char *cs, const char *ct)
+#if defined(CONFIG_CMD_I2C) && \
+		(!defined(CONFIG_DM_I2C) || defined(CONFIG_DM_I2C_COMPAT))
+	EXPORT_FUNC(i2c_write, int, i2c_write, uchar, uint, int , uchar * , int)
+	EXPORT_FUNC(i2c_read, int, i2c_read, uchar, uint, int , uchar * , int)
+#else
+	EXPORT_FUNC(dummy, void, i2c_write, void)
+	EXPORT_FUNC(dummy, void, i2c_read, void)
+#endif
+
+#if !defined(CONFIG_CMD_SPI) || defined(CONFIG_DM_SPI)
+	EXPORT_FUNC(dummy, void, spi_init, void)
+	EXPORT_FUNC(dummy, void, spi_setup_slave, void)
+	EXPORT_FUNC(dummy, void, spi_free_slave, void)
+#else
+	EXPORT_FUNC(spi_init, void, spi_init, void)
+	EXPORT_FUNC(spi_setup_slave, struct spi_slave *, spi_setup_slave,
+		    unsigned int, unsigned int, unsigned int, unsigned int)
+	EXPORT_FUNC(spi_free_slave, void, spi_free_slave, struct spi_slave *)
+#endif
+#ifndef CONFIG_CMD_SPI
+	EXPORT_FUNC(dummy, void, spi_claim_bus, void)
+	EXPORT_FUNC(dummy, void, spi_release_bus, void)
+	EXPORT_FUNC(dummy, void, spi_xfer, void)
+#else
+	EXPORT_FUNC(spi_claim_bus, int, spi_claim_bus, struct spi_slave *)
+	EXPORT_FUNC(spi_release_bus, void, spi_release_bus, struct spi_slave *)
+	EXPORT_FUNC(spi_xfer, int, spi_xfer, struct spi_slave *,
+		    unsigned int, const void *, void *, unsigned long)
+#endif
+	EXPORT_FUNC(ustrtoul, unsigned long, ustrtoul,
+		    const char *, char **, unsigned int)
+	EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull,
+		    const char *, char **, unsigned int)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 3d14d5f1..6747619 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -73,7 +73,7 @@
 	const void *fdt_blob;	/* Our device tree, NULL if none */
 	void *new_fdt;		/* Relocated FDT */
 	unsigned long fdt_size;	/* Space reserved for relocated FDT */
-	void **jt;		/* jump table */
+	struct jt_funcs *jt;		/* jump table */
 	char env_buf[32];	/* buffer for getenv() before reloc. */
 #ifdef CONFIG_TRACE
 	void		*trace_buff;	/* The trace buffer */
diff --git a/include/exports.h b/include/exports.h
index 41d5085..205affe 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -3,6 +3,8 @@
 
 #ifndef __ASSEMBLY__
 
+struct spi_slave;
+
 /* These are declarations of exported functions available in C code */
 unsigned long get_version(void);
 int  getc(void);
@@ -10,22 +12,23 @@
 void putc(const char);
 void puts(const char*);
 int printf(const char* fmt, ...);
-void install_hdlr(int, void (*interrupt_handler_t)(void *), void*);
+void install_hdlr(int, interrupt_handler_t, void*);
 void free_hdlr(int);
 void *malloc(size_t);
 void free(void*);
 void __udelay(unsigned long);
 unsigned long get_timer(unsigned long);
 int vprintf(const char *, va_list);
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base);
 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
 char *getenv (const char *name);
 int setenv (const char *varname, const char *varvalue);
-long simple_strtol(const char *cp,char **endp,unsigned int base);
-int strcmp(const char * cs,const char * ct);
+long simple_strtol(const char *cp, char **endp, unsigned int base);
+int strcmp(const char *cs, const char *ct);
 unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
 unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
-#if defined(CONFIG_CMD_I2C)
+#if defined(CONFIG_CMD_I2C) && \
+		(!defined(CONFIG_DM_I2C) || defined(CONFIG_DM_I2C_COMPAT))
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
 #endif
@@ -34,15 +37,14 @@
 
 #endif    /* ifndef __ASSEMBLY__ */
 
-enum {
-#define EXPORT_FUNC(x) XF_ ## x ,
+struct jt_funcs {
+#define EXPORT_FUNC(impl, res, func, ...) res(*func)(__VA_ARGS__);
 #include <_exports.h>
 #undef EXPORT_FUNC
-
-	XF_MAX
 };
 
-#define XF_VERSION	6
+
+#define XF_VERSION	7
 
 #if defined(CONFIG_X86)
 extern gd_t *global_data;