Index: drivers/timer/soclib/timer-soclib.c
===================================================================
--- drivers/timer/soclib/timer-soclib.c	(revision 1735)
+++ drivers/timer/soclib/timer-soclib.c	(working copy)
@@ -157,17 +157,24 @@
 
 const struct driver_s	timer_soclib_drv =
 {
-  .class		= device_class_timer,
+  .funcs_offset = {
+    [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+    [device_class_timer] = 0,
+  },
   .id_table		= timer_soclib_ids,
   .f_init		= timer_soclib_init,
   .f_cleanup		= timer_soclib_cleanup,
   .f_irq		= timer_soclib_irq,
-  .f.timer = {
-    .f_setcallback	= timer_soclib_setcallback,
-    .f_setperiod	= timer_soclib_setperiod,
-    .f_setvalue		= timer_soclib_setvalue,
-    .f_getvalue		= timer_soclib_getvalue,
-  }
+  .funcs = {
+    {
+      .timer = {
+        .f_setcallback	= timer_soclib_setcallback,
+        .f_setperiod	= timer_soclib_setperiod,
+        .f_setvalue		= timer_soclib_setvalue,
+        .f_getvalue		= timer_soclib_getvalue,
+      },
+    },
+  },
 };
 
 REGISTER_DRIVER(timer_soclib_drv);
Index: drivers/icu/soclib-xicu/xicu-soclib.c
===================================================================
--- drivers/icu/soclib-xicu/xicu-soclib.c	(revision 1735)
+++ drivers/icu/soclib-xicu/xicu-soclib.c	(working copy)
@@ -216,16 +216,23 @@
 
 const struct driver_s	xicu_root_drv =
 {
-	.class           = device_class_timer,
+    .funcs_offset = {
+        [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+        [device_class_timer] = 0,
+    },
 	.id_table        = xicu_root_ids,
 	.f_init          = xicu_root_init,
 	.f_cleanup       = xicu_root_cleanup,
-	.f.timer = {
-		.f_setcallback	= xicu_timer_setcallback,
-		.f_setperiod	= xicu_timer_setperiod,
-		.f_setvalue		= xicu_timer_setvalue,
-		.f_getvalue		= xicu_timer_getvalue,
-	}
+    .funcs = {
+        {
+            .timer = {
+                .f_setcallback	= xicu_timer_setcallback,
+                .f_setperiod	= xicu_timer_setperiod,
+                .f_setvalue		= xicu_timer_setvalue,
+                .f_getvalue		= xicu_timer_getvalue,
+            },
+        },
+    },
 };
 
 REGISTER_DRIVER(xicu_root_drv);
Index: drivers/icu/soclib-xicu/xicu-soclib-filter.c
===================================================================
--- drivers/icu/soclib-xicu/xicu-soclib-filter.c	(revision 1735)
+++ drivers/icu/soclib-xicu/xicu-soclib-filter.c	(working copy)
@@ -127,20 +127,27 @@
 
 const struct driver_s	xicu_filter_drv =
 {
-	.class           = device_class_icu,
+    .funcs_offset = {
+        [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+        [device_class_icu] = 0,
+    },
 	.id_table        = xicu_filter_ids,
 	.f_irq           = xicu_filter_handler,
 	.f_init          = xicu_filter_init,
 	.f_cleanup       = xicu_filter_cleanup,
-	.f.icu = {
-		.f_enable    = xicu_filter_enable,
-		.f_sethndl   = xicu_filter_sethndl,
-		.f_delhndl   = xicu_filter_delhndl,
+    .funcs = {
+        {
+            .icu = {
+                .f_enable    = xicu_filter_enable,
+                .f_sethndl   = xicu_filter_sethndl,
+                .f_delhndl   = xicu_filter_delhndl,
 #ifdef CONFIG_HEXO_IPI
-		.f_sendipi   = xicu_filter_sendipi,
-		.f_setup_ipi_ep  = xicu_filter_setup_ipi_ep,
+                .f_sendipi   = xicu_filter_sendipi,
+                .f_setup_ipi_ep  = xicu_filter_setup_ipi_ep,
 #endif
-	}
+            },
+        },
+    },
 };
 
 REGISTER_DRIVER(xicu_filter_drv);
Index: drivers/icu/mips/icu-mips.c
===================================================================
--- drivers/icu/mips/icu-mips.c	(revision 1735)
+++ drivers/icu/mips/icu-mips.c	(working copy)
@@ -135,16 +135,23 @@
 
 const struct driver_s	icu_mips_drv =
 {
-	.class		= device_class_icu,
+    .funcs_offset = {
+        [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+        [device_class_icu] = 0,
+    },
     .id_table   = icu_mips_ids,
 	.f_init		= icu_mips_init,
 	.f_irq      = (dev_irq_t *)icu_mips_handler,
 	.f_cleanup		= icu_mips_cleanup,
-	.f.icu = {
-		.f_enable		= icu_mips_enable,
-		.f_sethndl		= icu_mips_sethndl,
-		.f_delhndl		= icu_mips_delhndl,
-	}
+    .funcs = {
+        {
+            .icu = {
+                .f_enable		= icu_mips_enable,
+                .f_sethndl		= icu_mips_sethndl,
+                .f_delhndl		= icu_mips_delhndl,
+            },
+        },
+    },
 };
 
 REGISTER_DRIVER(icu_mips_drv);
Index: drivers/icu/soclib-icu/icu-soclib.c
===================================================================
--- drivers/icu/soclib-icu/icu-soclib.c	(revision 1735)
+++ drivers/icu/soclib-icu/icu-soclib.c	(working copy)
@@ -94,16 +94,23 @@
 
 const struct driver_s	icu_soclib_drv =
 {
-  .class		= device_class_icu,
+  .funcs_offset = {
+    [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+    [device_class_icu] = 0,
+  },
   .id_table		= icu_soclib_ids,
   .f_init		= icu_soclib_init,
   .f_cleanup		= icu_soclib_cleanup,
   .f_irq            = icu_soclib_handler,
-  .f.icu = {
-    .f_enable		= icu_soclib_enable,
-    .f_sethndl		= icu_soclib_sethndl,
-    .f_delhndl		= icu_soclib_delhndl,
-  }
+  .funcs = {
+    {
+      .icu = {
+        .f_enable		= icu_soclib_enable,
+        .f_sethndl		= icu_soclib_sethndl,
+        .f_delhndl		= icu_soclib_delhndl,
+      },
+    },
+  },
 };
 
 REGISTER_DRIVER(icu_soclib_drv);
Index: drivers/drivers.config
===================================================================
--- drivers/drivers.config	(revision 1735)
+++ drivers/drivers.config	(working copy)
@@ -11,6 +11,12 @@
   default defined
 %config end
 
+%config CONFIG_DRIVER_MULTICLASS
+  parent CONFIG_DEVICE
+  desc Support more than one class in a driver at the same time
+  default defined
+%config end
+
 %config CONFIG_DRIVER_CHAR
   parent CONFIG_DEVICE
   flags meta
Index: drivers/include/device/block.h
===================================================================
--- drivers/include/device/block.h	(revision 1735)
+++ drivers/include/device/block.h	(working copy)
@@ -23,20 +23,18 @@
  * @file
  * @module{Device drivers}
  * @short Block device driver API
- */                                                                 
+ */
 
 #ifndef __DEVICE_BLOCK_H__
 #define __DEVICE_BLOCK_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <hexo/gpct_platform_hexo.h>
 #include <gpct/cont_clist.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -78,7 +76,7 @@
     required by the driver. */
 
 struct dev_block_rq_s
-{  
+{
   CONTAINER_ENTRY_TYPE(CLIST)	queue_entry;
 
   enum dev_block_rq_type_e	type;    //< request type and flags
@@ -100,9 +98,6 @@
 #define DEVBLOCK_REQUEST(n)	void (n) (struct device_s *dev,	\
 					  struct dev_block_rq_s *rq)
 
-/** Block device class request() methode shortcut */
-
-#define dev_block_request(dev, ...) (dev)->drv->f.blk.f_request(dev, __VA_ARGS__ )
 /**
    Block device request function type. Request count data blocks
    from the device.
@@ -128,10 +123,6 @@
 /** Block device class getparams() function tempate. */
 #define DEVBLOCK_GETPARAMS(n)	const struct dev_block_params_s * (n) (struct device_s *dev)
 
-/** Block device class getparams() methode shortcut */
-
-#define dev_block_getparams(dev) (dev)->drv->f.blk.f_getparams(dev)
-
 /**
    Block device getparams function type.
 
@@ -147,10 +138,6 @@
 /** Block device class getrqsize() function tempate. */
 #define DEVBLOCK_GETRQSIZE(n)	size_t (n) (struct device_s *dev)
 
-/** Block device class getrqsize() methode shortcut */
-
-#define dev_block_getrqsize(dev) (dev)->drv->f.blk.f_getrqsize(dev)
-
 /**
    Block device getrqsize function type.
 
@@ -171,6 +158,37 @@
 };
 
 
+
+/** Block device class request() methode shortcut */
+static inline
+void dev_block_request(struct device_s *dev, struct dev_block_rq_s *rq)
+{
+    const struct dev_class_block_s *funcs =
+        driver_class_funcs(dev->drv, device_class_block);
+
+    return funcs->f_request(dev, rq);
+}
+
+/** Block device class getparams() methode shortcut */
+static inline
+const struct dev_block_params_s *dev_block_getparams(struct device_s *dev)
+{
+    const struct dev_class_block_s *funcs =
+        driver_class_funcs(dev->drv, device_class_block);
+
+    return funcs->f_getparams(dev);
+}
+
+/** Block device class getrqsize() methode shortcut */
+static inline
+size_t dev_block_getrqsize(struct device_s *dev)
+{
+    const struct dev_class_block_s *funcs =
+        driver_class_funcs(dev->drv, device_class_block);
+
+    return funcs->f_getrqsize(dev);
+}
+
 /** Synchronous helper read function. This function use the scheduler
     api to put current context in wait state if no data is available
     from device yet. This function is equivalent to
Index: drivers/include/device/spi.h
===================================================================
--- drivers/include/device/spi.h	(revision 1735)
+++ drivers/include/device/spi.h	(working copy)
@@ -28,15 +28,13 @@
 #ifndef __DEVICE_SPI_H__
 #define __DEVICE_SPI_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <hexo/gpct_platform_hexo.h>
 #include <gpct/cont_clist.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 struct dev_spi_rq_s;
@@ -249,9 +247,6 @@
 /** Spi device class request() function tempate. */
 #define DEVSPI_REQUEST(n)	void  (n) (struct device_s *dev, struct dev_spi_rq_s *rq)
 
-/** Spi device class request() methode shortcut */
-#define dev_spi_request(dev, ...) (dev)->drv->f.spi.f_request(dev, __VA_ARGS__ )
-
 /**
    Spi device class request() function type. Enqueue a request.
 
@@ -264,9 +259,6 @@
 /** Spi device class set_baudrate() function tempate. */
 #define DEVSPI_SET_BAUDRATE(n)	uint32_t  (n) (struct device_s *dev, uint_fast8_t device_id, uint32_t br, uint_fast8_t xfer_delay, uint_fast8_t cs_delay)
 
-/** Spi device class request() methode shortcut */
-#define dev_spi_set_baudrate(dev, ...) (dev)->drv->f.spi.f_set_baudrate(dev, __VA_ARGS__ )
-
 /**
    Spi device class set_baudrate() function type. Change clock for device id.
 
@@ -297,9 +289,6 @@
 		bool_t keep_cs_active											\
 		)
 
-/** Spi device class request() methode shortcut */
-#define dev_spi_set_data_format(dev, ...) (dev)->drv->f.spi.f_set_data_format(dev, __VA_ARGS__ )
-
 /**
    Spi device class set_data_format() function type. Change communication protocol.
 
@@ -320,5 +309,44 @@
   devspi_set_data_format_t		*f_set_data_format;
 };
 
+/** Spi device class request() methode shortcut */
+static inline
+void  dev_spi_request (struct device_s *dev, struct dev_spi_rq_s *rq)
+{
+    const struct dev_class_spi_s *funcs =
+        driver_class_funcs(dev->drv, device_class_spi);
+
+    return funcs->f_request(dev, rq);
+}
+
+/** Spi device class request() methode shortcut */
+static inline
+uint32_t  dev_spi_set_baudrate (struct device_s *dev,
+                                uint_fast8_t device_id, uint32_t br,
+                                uint_fast8_t xfer_delay, uint_fast8_t cs_delay)
+{
+    const struct dev_class_spi_s *funcs =
+        driver_class_funcs(dev->drv, device_class_spi);
+
+    return funcs->f_set_baudrate(dev, device_id, br, xfer_delay, cs_delay);
+}
+
+/** Spi device class request() methode shortcut */
+static inline
+error_t  dev_spi_set_data_format (
+    struct device_s *dev,
+    uint_fast8_t device_id,
+    uint_fast8_t bits_per_word,
+    enum spi_mode_e spi_mode,
+    bool_t keep_cs_active
+    )
+{
+    const struct dev_class_spi_s *funcs =
+        driver_class_funcs(dev->drv, device_class_spi);
+
+    return funcs->f_set_data_format(dev, device_id, bits_per_word, spi_mode, keep_cs_active);
+}
+
+
 #endif
 
Index: drivers/include/device/driver.h
===================================================================
--- drivers/include/device/driver.h	(revision 1735)
+++ drivers/include/device/driver.h	(working copy)
@@ -32,249 +32,93 @@
 #include <hexo/error.h>
 #include <device/device.h>
 
+/* Forward declaration of type in device/driver_binder.h */
+struct devenum_ident_s;
 
-#define PARAM_DATATYPE_INT 1
-#define PARAM_DATATYPE_DEVICE_PTR 2
-#define PARAM_DATATYPE_ADDR 3
-#define PARAM_DATATYPE_BOOL 4
-
-/**
-   A link from a device property and a field in the parameter
-   structure of a driver init()
- */
-struct driver_param_binder_s
-{
-	const char *param_name;
-	uint16_t struct_offset;
-	uint8_t datatype;
-	uint8_t datalen;
-};
-
-/**
-   Helper macro to create an entry in a struct driver_param_binder_s
-
-   @param _struct_type full type name of the parameter structure type
-   @param _struct_entry field name in the parameter structure
-   @param _datatype type of the data chosen in the PARAM_DATATYPE_*
- */
-#define PARAM_BIND(_struct_type, _struct_entry, _datatype)			    \
-	{																	\
-		.param_name = #_struct_entry,									\
-		.struct_offset = __builtin_offsetof(_struct_type, _struct_entry), \
-		.datatype = _datatype,										    \
-		.datalen = sizeof(((_struct_type *)0)->_struct_entry),		    \
-	}
-
-#define DEVENUM_TYPE_PCI 0x01
-#define DEVENUM_TYPE_ISA 0x02
-#define DEVENUM_TYPE_ATA 0x03
-#define DEVENUM_TYPE_FDTNAME 0x04
-
-/** device structure identification informations. wildcard values are
-    enum driver dependent */
-struct devenum_ident_s
-{
-	uint8_t type;
-	union {
-		struct {
-			uint16_t vendor;
-			uint16_t device;
-			uint32_t class;
-		} pci;
-		struct {
-			uint16_t vendor;
-		} isa;
-		struct {
-			const char *name;
-			size_t param_size;
-			const struct driver_param_binder_s *binder;
-		} fdtname;
-		struct {
-			const char *str;
-		} ata;
-	};
-};
-
-
-/**
-   Shortcut for creating a PCI entry in a static devenum_ident_s
-   array.
-
-   @param _vendor the vendor id to match, -1 for wildcard
-   @param _device the device id to match, -1 for wildcard
-   @param _class the class to match, -1 for wildcard
- */
-#define DEVENUM_PCI_ENTRY(_vendor, _device, _class)		\
-	{ .type = DEVENUM_TYPE_PCI, { .pci = {				\
-				.vendor = _vendor, .device = _device,	\
-				.class = _class } } }
-
-/**
-   Shortcut for creating an ISA entry in a static devenum_ident_s
-   array.
-
-   @param _vendor the vendor id to match
- */
-#define DEVENUM_ISA_ENTRY(_vendor)						\
-	{ .type = DEVENUM_TYPE_PCI, { .isa = {				\
-				.vendor = _vendor } } }
-
-/**
-   Shortcut for creating an ATA entry in a static devenum_ident_s
-   array.
-
-   @param _str the string to match from the device
- */
-#define DEVENUM_ATA_ENTRY(_str)							\
-	{ .type = DEVENUM_TYPE_ATA, { .ata = {				\
-				.str = _str } } }
-
-/**
-   Shortcut for creating a flat-device-tree entry in a static
-   devenum_ident_s array.
-
-   @param _name The string to match from the device-tree
-   @param _binder The data binder table pointer for the fdt to param conversion
- */
-#define DEVENUM_FDTNAME_ENTRY(_name, _psize, _binder)	\
-	{ .type = DEVENUM_TYPE_FDTNAME, { .fdtname = {		\
-				.name = _name, .param_size = _psize,	\
-				.binder = _binder } } }
-
-
 /** device driver object structure */
 
-#define DRV_MAX_FUNC_COUNT	6
+#define DRV_MAX_FUNC_COUNT  6
 
-struct driver_s
+union driver_func_s
 {
-  /* device class */
-  enum device_class_e		class;
-
-  /* device identifier table for detection (optional) */
-  const struct devenum_ident_s	*id_table;
-
-  dev_create_t			*f_create;
-  dev_init_t			*f_init;
-  dev_cleanup_t			*f_cleanup;
-  dev_irq_t			*f_irq;
-
-  union {
-    void			*ptrs[DRV_MAX_FUNC_COUNT];
-
+    void *ptrs[DRV_MAX_FUNC_COUNT];
 #ifdef __DEVICE_CHAR_H__
-    struct dev_class_char_s	chr;
+    struct dev_class_char_s chr;
 #endif
-
 #ifdef __DEVICE_ICU_H__
-    /** interrupt controller devices */
-    struct dev_class_icu_s	icu;
+    struct dev_class_icu_s icu;
 #endif
-
 #ifdef __DEVICE_FB_H__
-    /** frame buffer devices */
-    struct dev_class_fb_s	fb;
+    struct dev_class_fb_s fb;
 #endif
-
 #ifdef __DEVICE_TIMER_H__
-    struct dev_class_timer_s	timer;
+    struct dev_class_timer_s timer;
 #endif
-
 #ifdef __DEVICE_INPUT_H__
-    struct dev_class_input_s	input;
+    struct dev_class_input_s input;
 #endif
-
 #ifdef __DEVICE_ENUM_H__
-    /** device enumerator class */
-    struct dev_class_enum_s	denum;
+    struct dev_class_enum_s denum;
 #endif
-
 #ifdef __DEVICE_NET_H__
-    struct dev_class_net_s	net;
+    struct dev_class_net_s net;
 #endif
-
 #ifdef __DEVICE_SOUND_H__
-    struct dev_class_sound_s	sound;
+    struct dev_class_sound_s sound;
 #endif
-
 #ifdef __DEVICE_BLOCK_H__
-    struct dev_class_block_s	blk;
+    struct dev_class_block_s blk;
 #endif
-
 #ifdef __DEVICE_SPI_H__
-    struct dev_class_spi_s	spi;
+    struct dev_class_spi_s spi;
 #endif
-
 #ifdef __DEVICE_LCD_H__
-    struct dev_class_lcd_s	lcd;
+    struct dev_class_lcd_s lcd;
 #endif
-
 #ifdef __DEVICE_GPIO_H__
-    struct dev_class_gpio_s	gpio;
+    struct dev_class_gpio_s gpio;
 #endif
-
 #ifdef __DEVICE_I2C_H__
-    struct dev_class_i2c_s	i2c;
+    struct dev_class_i2c_s i2c;
 #endif
-
 #ifdef __DEVICE_MEM_H__
-    struct dev_class_mem_s	mem;
+    struct dev_class_mem_s mem;
 #endif
-  } f;
 };
 
-/**
-   Registers a driver (struct driver_s) in the global_driver_registry
-   table.
- */
-#if defined(CONFIG_ARCH_EMU_DARWIN)
-#define REGISTER_DRIVER(name) \
-	const __attribute__((section ("__DATA, __drivers"))) \
-	const struct driver_s *name##_drv_ptr = &name
-#else
-#define REGISTER_DRIVER(name) \
-	const __attribute__((section (".drivers"))) \
-	const struct driver_s *name##_drv_ptr = &name
-#endif
+struct driver_s
+{
+    /** device identifier table for detection (optional) */
+    const struct devenum_ident_s *id_table;
 
-/**
-   Try to get a driver registered with these characteristics
+    dev_create_t   *f_create;
+    dev_init_t     *f_init;
+    dev_cleanup_t  *f_cleanup;
+    dev_irq_t      *f_irq;
 
-   @param vendor Vendor of PCI device
-   @param vendor Device of PCI device
-   @param vendor Class of PCI device
-   @return A driver if found, NULL otherwise
- */
-const struct driver_s *driver_get_matching_pci(
-	uint16_t vendor,
-	uint16_t device,
-	uint32_t class);
+#if defined(CONFIG_DRIVER_MULTICLASS)
+    uint8_t funcs_offset[DEVICE_CLASS_COUNT];
+#endif
 
-/**
-   Try to get a driver registered with these characteristics
+    union driver_func_s funcs[];
+};
 
-   @param vendor Vendor of ISA device
-   @return A driver if found, NULL otherwise
- */
-const struct driver_s *driver_get_matching_isa(
-	uint16_t vendor);
+static inline
+const void *driver_class_funcs(
+    const struct driver_s *drv,
+    enum device_class_e class)
+{
+#if defined(CONFIG_DRIVER_MULTICLASS)
+    const uint8_t offset = drv->funcs_offset[class];
 
-/**
-   Try to get a driver registered with these characteristics
+    assert(offset != DEVICE_CLASS_UNAVAILABLE);
+#else
+    const uint8_t offset = 0;
+#endif
 
-   @param name Name of ata device
-   @return A driver if found, NULL otherwise
- */
-const struct driver_s *driver_get_matching_ata(
-	const char *name);
+    return &drv->funcs[offset];
+}
 
-/**
-   Try to get a driver registered with these characteristics
+#include <device/driver_binder.h>
 
-   @param name Name of device_type in the FDT
-   @return A driver if found, NULL otherwise
- */
-const struct driver_s *driver_get_matching_fdtname(
-	const char *name);
-
 #endif
Index: drivers/include/device/gpio.h
===================================================================
--- drivers/include/device/gpio.h	(revision 1735)
+++ drivers/include/device/gpio.h	(working copy)
@@ -28,15 +28,13 @@
 #ifndef __DEVICE_GPIO_H__
 #define __DEVICE_GPIO_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <hexo/gpct_platform_hexo.h>
 #include <gpct/cont_clist.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -67,10 +65,7 @@
  */
 typedef DEVGPIO_SET_WAY(devgpio_set_way_t);
 
-/** Gpio device class set_way() methode shortcut */
-#define dev_gpio_set_way(dev, ...) (dev)->drv->f.gpio.f_set_way(dev, __VA_ARGS__ )
 
-
 /** Gpio device class set_value() function tempate. */
 #define DEVGPIO_SET_VALUE(n)	error_t  (n) (struct device_s *dev,		\
 											  devgpio_id_t gpio,			\
@@ -89,10 +84,7 @@
  */
 typedef DEVGPIO_SET_VALUE(devgpio_set_value_t);
 
-/** Gpio device class set_value() methode shortcut */
-#define dev_gpio_set_value(dev, ...) (dev)->drv->f.gpio.f_set_value(dev, __VA_ARGS__ )
 
-
 /** Gpio device class set_pullup() function tempate. */
 #define DEVGPIO_SET_PULLUP(n)	error_t  (n) (struct device_s *dev,		\
 											  devgpio_id_t gpio,			\
@@ -111,10 +103,7 @@
  */
 typedef DEVGPIO_SET_PULLUP(devgpio_set_pullup_t);
 
-/** Gpio device class set_pullup() methode shortcut */
-#define dev_gpio_set_pullup(dev, ...) (dev)->drv->f.gpio.f_set_pullup(dev, __VA_ARGS__ )
 
-
 /** Gpio device class assign_to_peripheral() function tempate. */
 #define DEVGPIO_ASSIGN_TO_PERIPHERAL(n)	error_t  (n) (struct device_s *dev,	\
 													  devgpio_id_t gpio,	\
@@ -135,10 +124,7 @@
  */
 typedef DEVGPIO_ASSIGN_TO_PERIPHERAL(devgpio_assign_to_peripheral_t);
 
-/** Gpio device class assign_to_peripheral() methode shortcut */
-#define dev_gpio_assign_to_peripheral(dev, ...) (dev)->drv->f.gpio.f_assign_to_peripheral(dev, __VA_ARGS__ )
 
-
 /** Gpio device class get_value() function tempate. */
 #define DEVGPIO_GET_VALUE(n)	bool_t  (n) (struct device_s *dev,	   \
 											 devgpio_id_t gpio)
@@ -154,10 +140,7 @@
  */
 typedef DEVGPIO_GET_VALUE(devgpio_get_value_t);
 
-/** Gpio device class get_value() methode shortcut */
-#define dev_gpio_get_value(dev, ...) (dev)->drv->f.gpio.f_get_value(dev, __VA_ARGS__ )
 
-
 enum devgpio_event_e
 {
 	GPIO_EDGE_RAISING,
@@ -207,11 +190,8 @@
  */
 typedef DEVGPIO_REGISTER_IRQ(devgpio_register_irq_t);
 
-/** Gpio device class register_irq() methode shortcut */
-#define dev_gpio_register_irq(dev, ...) (dev)->drv->f.gpio.f_register_irq(dev, __VA_ARGS__ )
 
 
-
 /** Gpio device class methodes */
 struct dev_class_gpio_s
 {
@@ -223,5 +203,79 @@
   devgpio_register_irq_t	*f_register_irq;
 };
 
+
+/** Gpio device class set_way() methode shortcut */
+static inline
+error_t dev_gpio_set_way(struct device_s *dev,
+                         devgpio_id_t gpio,
+                         gpio devgpio_way_e way)
+{
+    const struct dev_class_gpio_s *funcs =
+        driver_class_funcs(dev->drv, device_class_gpio);
+
+    return funcs->f_set_way(dev, gpio, way);
+}
+
+/** Gpio device class set_value() methode shortcut */
+static inline
+error_t  dev_gpio_set_value(struct device_s *dev,
+                            devgpio_id_t gpio,
+                            bool_t value)
+{
+    const struct dev_class_gpio_s *funcs =
+        driver_class_funcs(dev->drv, device_class_gpio);
+
+    return funcs->f_set_value(dev, gpio, value);
+}
+
+/** Gpio device class set_pullup() methode shortcut */
+static inline
+error_t  dev_gpio_set_pullup(struct device_s *dev,
+                             devgpio_id_t gpio,
+                             bool_t pullup)
+{
+    const struct dev_class_gpio_s *funcs =
+        driver_class_funcs(dev->drv, device_class_gpio);
+
+    return funcs->f_set_pullup(dev, gpio, pullup);
+}
+
+/** Gpio device class assign_to_peripheral() methode shortcut */
+static inline
+error_t  dev_gpio_assign_to_peripheral(struct device_s *dev,
+                                       devgpio_id_t gpio,
+                                       uint_fast8_t device_id)
+{
+    const struct dev_class_gpio_s *funcs =
+        driver_class_funcs(dev->drv, device_class_gpio);
+
+    return funcs->f_assign_to_peripheral(dev, gpio, device_id);
+}
+
+/** Gpio device class get_value() methode shortcut */
+static inline
+bool_t  dev_gpio_get_value(struct device_s *dev,
+                           devgpio_id_t gpio)
+{
+    const struct dev_class_gpio_s *funcs =
+        driver_class_funcs(dev->drv, device_class_gpio);
+
+    return funcs->f_get_value(dev, gpio);
+}
+
+/** Gpio device class register_irq() methode shortcut */
+static inline
+error_t dev_gpio_register_irq(struct device_s *dev,
+                              devgpio_id_t gpio,
+                              enum devgpio_event_e event,
+                              devgpio_irq_t *callback,
+                              void *private_data)
+{
+    const struct dev_class_gpio_s *funcs =
+        driver_class_funcs(dev->drv, device_class_gpio);
+
+    return funcs->f_register_irq(dev, gpio, event, callback, private_data);
+}
+
 #endif
 
Index: drivers/include/device/input.h
===================================================================
--- drivers/include/device/input.h	(revision 1735)
+++ drivers/include/device/input.h	(working copy)
@@ -28,13 +28,11 @@
 #ifndef __DEVICE_INPUT_H__
 #define __DEVICE_INPUT_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -68,7 +66,6 @@
 #define DEVINPUT_INFO(n)	void  (n) (struct device_s *dev,		\
 					   struct devinput_info_s *info)
 
-#define dev_input_info(dev, ...) (dev)->drv->f.input.f_info(dev, __VA_ARGS__ )
 /**
    Input device class info() function type. This function get
    informations about available controles.
@@ -83,7 +80,6 @@
 #define DEVINPUT_READ(n)	devinput_value_t (n) (struct device_s *dev,	\
 						      devinput_ctrlid_t id)
 
-#define dev_input_read(dev, ...) (dev)->drv->f.input.f_read(dev, __VA_ARGS__ )
 /**
    Input device class read() function type. This function read control
    current value.
@@ -100,7 +96,6 @@
 					     devinput_ctrlid_t id,	\
 					     devinput_value_t value)
 
-#define dev_input_write(dev, ...) (dev)->drv->f.input.f_write(dev, __VA_ARGS__ )
 /**
    Input device class write() function type. This function set control
    current value.
@@ -120,7 +115,6 @@
 					     devinput_callback_t *callback,	\
 					     void *priv)
 
-#define dev_input_setcallback(dev, ...) (dev)->drv->f.input.f_setcallback(dev, __VA_ARGS__ )
 /**
    Input device class setcallback() function type. This function set
    a new event handler for a control. Special DEVINPUT_CTRLID_ALL
@@ -146,6 +140,48 @@
   devinput_setcallback_t	*f_setcallback;
 };
 
+static inline
+void  dev_input_info(struct device_s *dev,
+                     struct devinput_info_s *info)
+{
+    const struct dev_class_input_s *funcs =
+        driver_class_funcs(dev->drv, device_class_input);
 
+    return funcs->f_info(dev, info);
+}
+
+static inline
+devinput_value_t dev_input_read(struct device_s *dev,
+                                devinput_ctrlid_t id)
+{
+    const struct dev_class_input_s *funcs =
+        driver_class_funcs(dev->drv, device_class_input);
+
+    return funcs->f_read(dev, id);
+}
+
+static inline
+error_t dev_input_write(struct device_s *dev,
+                        devinput_ctrlid_t id,
+                        devinput_value_t value)
+{
+    const struct dev_class_input_s *funcs =
+        driver_class_funcs(dev->drv, device_class_input);
+
+    return funcs->f_write(dev, id, value);
+}
+
+static inline
+error_t dev_input_setcallback(struct device_s *dev,
+                              uint_fast8_t type,
+                              devinput_ctrlid_t id,
+                              devinput_callback_t *callback,
+                              void *priv)
+{
+    const struct dev_class_input_s *funcs =
+        driver_class_funcs(dev->drv, device_class_input);
+
+    return funcs->f_setcallback(dev, type, id, callback, priv);
+}
+
 #endif
-
Index: drivers/include/device/device.h
===================================================================
--- drivers/include/device/device.h	(revision 1735)
+++ drivers/include/device/device.h	(working copy)
@@ -35,26 +35,55 @@
 #include <hexo/error.h>
 
 enum device_class_e
-  {
-    device_class_none = 0,
-
-    device_class_block,
+{
+#ifdef CONFIG_DRIVER_CHAR
     device_class_char,
-    device_class_enum,
+#endif
+#ifdef CONFIG_DRIVER_ICU
+    device_class_icu,
+#endif
+#ifdef CONFIG_DRIVER_FB
     device_class_fb,
-    device_class_icu,
+#endif
+#ifdef CONFIG_DRIVER_TIMER
+    device_class_timer,
+#endif
+#ifdef CONFIG_DRIVER_INPUT
     device_class_input,
+#endif
+#ifdef CONFIG_DRIVER_ENUM
+    device_class_enum,
+#endif
+#ifdef CONFIG_DRIVER_NET
     device_class_net,
+#endif
+#ifdef CONFIG_DRIVER_SOUND
     device_class_sound,
-    device_class_timer,
+#endif
+#ifdef CONFIG_DRIVER_BLOCK
+    device_class_block,
+#endif
+#ifdef CONFIG_DRIVER_SPI
     device_class_spi,
+#endif
+#ifdef CONFIG_DRIVER_LCD
     device_class_lcd,
+#endif
+#ifdef CONFIG_DRIVER_GPIO
     device_class_gpio,
+#endif
+#ifdef CONFIG_DRIVER_I2C
     device_class_i2c,
+#endif
+#ifdef CONFIG_DRIVER_MEM
     device_class_mem,
-  };
+#endif
 
+    DEVICE_CLASS_COUNT,
+};
 
+#define DEVICE_CLASS_UNAVAILABLE 0xff
+
 /** Common class irq() function template. */
 #define DEV_IRQ(n)	bool_t (n) (struct device_s *dev)
 
Index: drivers/include/device/lcd.h
===================================================================
--- drivers/include/device/lcd.h	(revision 1735)
+++ drivers/include/device/lcd.h	(working copy)
@@ -28,15 +28,13 @@
 #ifndef __DEVICE_LCD_H__
 #define __DEVICE_LCD_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <hexo/gpct_platform_hexo.h>
 #include <gpct/cont_clist.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -123,8 +121,6 @@
 
 typedef DEVLCD_REQUEST(devlcd_request_t);
 
-/** Lcd device class request() methode shortcut */
-#define dev_lcd_request(dev, ...) (dev)->drv->f.lcd.f_request(dev, __VA_ARGS__ )
 
 
 
@@ -140,8 +136,6 @@
 */
 typedef DEVLCD_GETINFO(devlcd_getinfo_t);
 
-/** Lcd device class getinfo() methode shortcut */
-#define dev_lcd_getinfo(dev) (dev)->drv->f.lcd.f_getinfo(dev)
 
 
 
@@ -152,7 +146,29 @@
   devlcd_getinfo_t	*f_getinfo;
 };
 
+/** Lcd device class request() methode shortcut */
+static inline
+error_t  dev_lcd_request(struct device_s *dev,
+                         struct lcd_req_s *req)
+{
+    const struct dev_class_lcd_s *funcs =
+        driver_class_funcs(dev->drv, device_class_lcd);
 
+    return funcs->f_request(dev, req);
+}
+
+/** Lcd device class getinfo() methode shortcut */
+static inline
+const struct lcd_info_s * dev_lcd_getinfo(struct device_s *dev)
+{
+    const struct dev_class_lcd_s *funcs =
+        driver_class_funcs(dev->drv, device_class_lcd);
+
+    return funcs->f_getinfo(dev);
+}
+
+
+
 ssize_t dev_lcd_set_palette(struct device_s *dev, struct lcd_pal_s *palette, size_t count);
 
 /**
Index: drivers/include/device/enum.h
===================================================================
--- drivers/include/device/enum.h	(revision 1735)
+++ drivers/include/device/enum.h	(working copy)
@@ -28,13 +28,11 @@
 #ifndef __DEVICE_ENUM_H__
 #define __DEVICE_ENUM_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 
+#include <device/driver_fw.h>
+
 /**
    Lookup function prototype macro
  */
@@ -50,11 +48,6 @@
  */
 typedef DEVENUM_LOOKUP(devenum_lookup_t);
 
-/**
-   Lookup function shortcut
- */
-#define dev_enum_lookup(dev, ...) (dev)->drv->f.denum.f_lookup(dev, __VA_ARGS__)
-
 #define DEV_ENUM_MAX_PATH_LEN 32
 
 struct dev_enum_info_s
@@ -82,15 +75,36 @@
  */
 typedef DEVENUM_INFO(devenum_info_t);
 
-/**
-   Info function shortcut
- */
-#define dev_enum_info(dev, ...) (dev)->drv->f.denum.f_info(dev, __VA_ARGS__)
-
 struct dev_class_enum_s
 {
 	devenum_lookup_t *f_lookup;
 	devenum_info_t *f_info;
 };
 
+/**
+   Lookup function shortcut
+ */
+static inline
+struct device_s *dev_enum_lookup(struct device_s *dev, const char *path)
+{
+    const struct dev_class_enum_s *funcs =
+        driver_class_funcs(dev->drv, device_class_enum);
+
+    return funcs->f_lookup(dev, path);
+}
+
+/**
+   Info function shortcut
+ */
+static inline
+error_t dev_enum_info(struct device_s *dev,
+                         struct device_s *child,
+                         struct dev_enum_info_s *info)
+{
+    const struct dev_class_enum_s *funcs =
+        driver_class_funcs(dev->drv, device_class_enum);
+
+    return funcs->f_info(dev, child, info);
+}
+
 #endif
Index: drivers/include/device/i2c.h
===================================================================
--- drivers/include/device/i2c.h	(revision 1735)
+++ drivers/include/device/i2c.h	(working copy)
@@ -28,15 +28,13 @@
 #ifndef __DEVICE_I2C_H__
 #define __DEVICE_I2C_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <hexo/gpct_platform_hexo.h>
 #include <gpct/cont_clist.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 struct dev_i2c_rq_s;
@@ -94,9 +92,6 @@
 /** I2c device class request() function tempate. */
 #define DEVI2C_REQUEST(n)	void  (n) (struct device_s *dev, struct dev_i2c_rq_s *rq)
 
-/** I2c device class request() methode shortcut */
-#define dev_i2c_request(dev, ...) (dev)->drv->f.i2c.f_request(dev, __VA_ARGS__ )
-
 /**
    I2c device class request() function type. Enqueue a request.
 
@@ -109,9 +104,6 @@
 /** I2c device class set_baudrate() function tempate. */
 #define DEVI2C_SET_BAUDRATE(n)	uint32_t  (n) (struct device_s *dev, uint32_t br)
 
-/** I2c device class request() methode shortcut */
-#define dev_i2c_set_baudrate(dev, ...) (dev)->drv->f.i2c.f_set_baudrate(dev, __VA_ARGS__ )
-
 /**
    I2c device class set_baudrate() function type. Change clock for device id.
 
@@ -129,7 +121,26 @@
   devi2c_set_baudrate_t		*f_set_baudrate;
 };
 
+/** I2c device class request() method shortcut */
+static inline
+void dev_i2c_request(struct device_s *dev, struct dev_i2c_rq_s *rq)
+{
+    const struct dev_class_i2c_s *funcs =
+        driver_class_funcs(dev->drv, device_class_i2c);
 
+    return funcs->i2c.f_request(dev, rq);
+}
+
+/** I2c device class set_baudrate() method shortcut */
+static inline
+uint32_t dev_i2c_set_baudrate(struct device_s *dev, uint32_t br)
+{
+    const struct dev_class_i2c_s *funcs =
+        driver_class_funcs(dev->drv, device_class_i2c);
+
+    return funcs->i2c.f_set_baudrate(dev, br);
+}
+
 error_t dev_i2c_wait_request(
 	struct device_s *dev,
 	struct dev_i2c_rq_s *rq);
@@ -170,6 +181,5 @@
 	return dev_i2c_wait_request(dev, &rq);
 }
 
-
 #endif
 
Index: drivers/include/device/char.h
===================================================================
--- drivers/include/device/char.h	(revision 1735)
+++ drivers/include/device/char.h	(working copy)
@@ -23,20 +23,18 @@
  * @file
  * @module{Device drivers}
  * @short Character device driver API
- */                                                                 
+ */
 
 #ifndef __DEVICE_CHAR_H__
 #define __DEVICE_CHAR_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <hexo/gpct_platform_hexo.h>
 #include <gpct/cont_clist.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 struct dev_char_rq_s;
@@ -86,9 +84,6 @@
 /** Char device class request() function tempate. */
 #define DEVCHAR_REQUEST(n)	void  (n) (struct device_s *dev, struct dev_char_rq_s *rq)
 
-/** Char device class request() methode shortcut */
-#define dev_char_request(dev, ...) (dev)->drv->f.chr.f_request(dev, __VA_ARGS__ )
-
 /**
    Char device class request() function type. Enqueue a read or write request.
 
@@ -105,6 +100,17 @@
 };
 
 
+
+/** Char device class request() methode shortcut */
+static inline
+void dev_char_request(struct device_s *dev, struct dev_char_rq_s *rq)
+{
+    const struct dev_class_char_s *funcs =
+        driver_class_funcs(dev->drv, device_class_char);
+
+    return funcs->f_request(dev, rq);
+}
+
 /** Synchronous helper read function. This function uses the scheduler
     api to put current context in wait state if no data is available
     from device yet. This function spins in a loop waiting for read
Index: drivers/include/device/mem.h
===================================================================
--- drivers/include/device/mem.h	(revision 1735)
+++ drivers/include/device/mem.h	(working copy)
@@ -27,13 +27,11 @@
 #ifndef __DEVICE_MEM_H__
 #define __DEVICE_MEM_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -51,9 +49,6 @@
 /** Mem device class get_info() function tempate. */
 #define DEVMEM_GET_INFO(n)	void  (n) (struct device_s *dev, struct dev_mem_info_s *info)
 
-/** Mem device class request() methode shortcut */
-#define dev_mem_get_info(dev, ...) (dev)->drv->f.mem.f_get_info(dev, __VA_ARGS__ )
-
 /**
    Mem device class get_info() function type. Get information about a ram device.
 
@@ -69,5 +64,16 @@
   devmem_get_info_t		*f_get_info;
 };
 
+/** Mem device class get_info() methode shortcut */
+static inline
+void dev_mem_get_info(struct device_s *dev, struct dev_mem_info_s *info)
+{
+
+    const struct dev_class_mem_s *funcs =
+        driver_class_funcs(dev->drv, device_class_mem);
+
+    return funcs->f_get_info(dev, info);
+}
+
 #endif
 
Index: drivers/include/device/driver_binder.h
===================================================================
--- drivers/include/device/driver_binder.h	(revision 0)
+++ drivers/include/device/driver_binder.h	(revision 0)
@@ -0,0 +1,196 @@
+/*
+    This file is part of MutekH.
+
+    MutekH 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.
+
+    MutekH 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 MutekH; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+    Copyright (c) 2006-2010, MutekH contributors
+*/
+
+/**
+ * @file
+ * @module{Device drivers}
+ * @short Driver dynamic binder definitions
+ */
+
+#ifndef __DRIVER_BINDER_H__
+#define __DRIVER_BINDER_H__
+
+#include <hexo/types.h>
+#include <hexo/error.h>
+
+#define PARAM_DATATYPE_INT 1
+#define PARAM_DATATYPE_DEVICE_PTR 2
+#define PARAM_DATATYPE_ADDR 3
+#define PARAM_DATATYPE_BOOL 4
+
+/**
+   A link from a device property and a field in the parameter
+   structure of a driver init()
+ */
+struct driver_param_binder_s
+{
+	const char *param_name;
+	uint16_t struct_offset;
+	uint8_t datatype;
+	uint8_t datalen;
+};
+
+/**
+   Helper macro to create an entry in a struct driver_param_binder_s
+
+   @param _struct_type full type name of the parameter structure type
+   @param _struct_entry field name in the parameter structure
+   @param _datatype type of the data chosen in the PARAM_DATATYPE_*
+ */
+#define PARAM_BIND(_struct_type, _struct_entry, _datatype)			    \
+	{																	\
+		.param_name = #_struct_entry,									\
+		.struct_offset = __builtin_offsetof(_struct_type, _struct_entry), \
+		.datatype = _datatype,										    \
+		.datalen = sizeof(((_struct_type *)0)->_struct_entry),		    \
+	}
+
+#define DEVENUM_TYPE_PCI 0x01
+#define DEVENUM_TYPE_ISA 0x02
+#define DEVENUM_TYPE_ATA 0x03
+#define DEVENUM_TYPE_FDTNAME 0x04
+
+/** device structure identification informations. wildcard values are
+    enum driver dependent */
+struct devenum_ident_s
+{
+	uint8_t type;
+	union {
+		struct {
+			uint16_t vendor;
+			uint16_t device;
+			uint32_t class;
+		} pci;
+		struct {
+			uint16_t vendor;
+		} isa;
+		struct {
+			const char *name;
+			size_t param_size;
+			const struct driver_param_binder_s *binder;
+		} fdtname;
+		struct {
+			const char *str;
+		} ata;
+	};
+};
+
+
+/**
+   Shortcut for creating a PCI entry in a static devenum_ident_s
+   array.
+
+   @param _vendor the vendor id to match, -1 for wildcard
+   @param _device the device id to match, -1 for wildcard
+   @param _class the class to match, -1 for wildcard
+ */
+#define DEVENUM_PCI_ENTRY(_vendor, _device, _class)		\
+	{ .type = DEVENUM_TYPE_PCI, { .pci = {				\
+				.vendor = _vendor, .device = _device,	\
+				.class = _class } } }
+
+/**
+   Shortcut for creating an ISA entry in a static devenum_ident_s
+   array.
+
+   @param _vendor the vendor id to match
+ */
+#define DEVENUM_ISA_ENTRY(_vendor)						\
+	{ .type = DEVENUM_TYPE_PCI, { .isa = {				\
+				.vendor = _vendor } } }
+
+/**
+   Shortcut for creating an ATA entry in a static devenum_ident_s
+   array.
+
+   @param _str the string to match from the device
+ */
+#define DEVENUM_ATA_ENTRY(_str)							\
+	{ .type = DEVENUM_TYPE_ATA, { .ata = {				\
+				.str = _str } } }
+
+/**
+   Shortcut for creating a flat-device-tree entry in a static
+   devenum_ident_s array.
+
+   @param _name The string to match from the device-tree
+   @param _binder The data binder table pointer for the fdt to param conversion
+ */
+#define DEVENUM_FDTNAME_ENTRY(_name, _psize, _binder)	\
+	{ .type = DEVENUM_TYPE_FDTNAME, { .fdtname = {		\
+				.name = _name, .param_size = _psize,	\
+				.binder = _binder } } }
+
+
+/**
+   Registers a driver (struct driver_s) in the global_driver_registry
+   table.
+*/
+#if defined(CONFIG_ARCH_EMU_DARWIN)
+#define REGISTER_DRIVER(name)                                          \
+    const __attribute__((section ("__DATA, __drivers")))               \
+    const struct driver_s *name##_drv_ptr = &name
+#else
+#define REGISTER_DRIVER(name)                                          \
+    const __attribute__((section (".drivers")))                        \
+    const struct driver_s *name##_drv_ptr = &name
+#endif
+
+/**
+   Try to get a driver registered with these characteristics
+
+   @param vendor Vendor of PCI device
+   @param vendor Device of PCI device
+   @param vendor Class of PCI device
+   @return A driver if found, NULL otherwise
+*/
+const struct driver_s *driver_get_matching_pci(
+    uint16_t vendor,
+    uint16_t device,
+    uint32_t class);
+
+/**
+   Try to get a driver registered with these characteristics
+
+   @param vendor Vendor of ISA device
+   @return A driver if found, NULL otherwise
+*/
+const struct driver_s *driver_get_matching_isa(
+    uint16_t vendor);
+
+/**
+   Try to get a driver registered with these characteristics
+
+   @param name Name of ata device
+   @return A driver if found, NULL otherwise
+*/
+const struct driver_s *driver_get_matching_ata(
+    const char *name);
+
+/**
+   Try to get a driver registered with these characteristics
+
+   @param name Name of device_type in the FDT
+   @return A driver if found, NULL otherwise
+*/
+const struct driver_s *driver_get_matching_fdtname(
+    const char *name);
+
+#endif /* __DRIVER_BINDER_H__ */

Property changes on: drivers/include/device/driver_binder.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + "Author Date Id Rev URL Revision"
Added: svn:eol-style
   + native

Index: drivers/include/device/timer.h
===================================================================
--- drivers/include/device/timer.h	(revision 1735)
+++ drivers/include/device/timer.h	(working copy)
@@ -28,13 +28,11 @@
 #ifndef __DEVICE_TIMER_H__
 #define __DEVICE_TIMER_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -59,8 +57,6 @@
     * @param priv private data passed to callback function
     */
 typedef DEVTIMER_SETCALLBACK(devtimer_setcallback_t);
-/** TIMER device class setcallback() function shortcut */
-#define dev_timer_setcallback(dev, ...) (dev)->drv->f.timer.f_setcallback(dev, __VA_ARGS__ )
 
 
 
@@ -76,8 +72,6 @@
     * @param period timer period
     */
 typedef DEVTIMER_SETPERIOD(devtimer_setperiod_t);
-/** TIMER device class setperiod() function shortcut */
-#define dev_timer_setperiod(dev, ...) (dev)->drv->f.timer.f_setperiod(dev, __VA_ARGS__ )
 
 
 
@@ -92,8 +86,6 @@
     * @param value new timer value
     */
 typedef DEVTIMER_SETVALUE(devtimer_setvalue_t);
-/** TIMER device class setvalue() function shortcut */
-#define dev_timer_setvalue(dev, ...) (dev)->drv->f.timer.f_setvalue(dev, __VA_ARGS__ )
 
 
 
@@ -108,8 +100,6 @@
     * @return current timer value
     */
 typedef DEVTIMER_GETVALUE(devtimer_getvalue_t);
-/** TIMER device class getvalue() function shortcut */
-#define dev_timer_getvalue(dev, ...) (dev)->drv->f.timer.f_getvalue(dev, __VA_ARGS__ )
 
 
 
@@ -123,6 +113,45 @@
   devtimer_setvalue_t			*f_setvalue;
 };
 
+/** Timer device class setcallback() function shortcut */
+static inline
+error_t dev_timer_setcallback(struct device_s *dev, uint_fast8_t id, devtimer_callback_t *callback, void *priv)
+{
+    const struct dev_class_timer_s *funcs =
+        driver_class_funcs(dev->drv, device_class_timer);
 
+    return funcs->f_setcallback(dev, id, callback, priv);
+}
+
+/** Timer device class setperiod() function shortcut */
+static inline
+error_t dev_timer_setperiod(struct device_s *dev, uint_fast8_t id, uintmax_t period)
+{
+    const struct dev_class_timer_s *funcs =
+        driver_class_funcs(dev->drv, device_class_timer);
+
+    return funcs->f_setperiod(dev, id, period);
+}
+
+/** Timer device class setvalue() function shortcut */
+static inline
+error_t dev_timer_setvalue(struct device_s *dev, uint_fast8_t id, uintmax_t value)
+{
+    const struct dev_class_timer_s *funcs =
+        driver_class_funcs(dev->drv, device_class_timer);
+
+    return funcs->f_setvalue(dev, id, value);
+}
+
+/** Timer device class getvalue() function shortcut */
+static inline
+uintmax_t dev_timer_getvalue(struct device_s *dev, uint_fast8_t id)
+{
+    const struct dev_class_timer_s *funcs =
+        driver_class_funcs(dev->drv, device_class_timer);
+
+    return funcs->f_getvalue(dev, id);
+}
+
 #endif
 
Index: drivers/include/device/icu.h
===================================================================
--- drivers/include/device/icu.h	(revision 1735)
+++ drivers/include/device/icu.h	(working copy)
@@ -28,14 +28,12 @@
 #ifndef __DEVICE_ICU_H__
 #define __DEVICE_ICU_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <device/device.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -53,11 +51,8 @@
     */
 typedef DEVICU_ENABLE(devicu_enable_t);
 
-/** ICU device class enable() function shortcut */
-#define dev_icu_enable(dev, ...) (dev)->drv->f.icu.f_enable(dev, __VA_ARGS__ )
 
 
-
 /** ICU device class sethndl() function template */
 #define DEVICU_SETHNDL(n)	error_t (n) (struct device_s *dev, uint_fast8_t irq, dev_irq_t *hndl, void *data)
 /** ICU device class sethndl() function type. Setup a new interrupt
@@ -70,8 +65,6 @@
     * @return negative error code
     */
 typedef DEVICU_SETHNDL(devicu_sethndl_t);
-/** ICU device class sethndl() function shortcut */
-#define dev_icu_sethndl(dev, ...) (dev)->drv->f.icu.f_sethndl(dev, __VA_ARGS__ )
 
 /** bind a device to this icu irq for an already configured device */	\
 #define DEV_ICU_BIND(icu_dev, dev, irq, callback)			\
@@ -95,8 +88,6 @@
     * @return negative error code
     */
 typedef DEVICU_DELHNDL(devicu_delhndl_t);
-/** ICU device class delhndl() function shortcut */
-#define dev_icu_delhndl(dev, ...) (dev)->drv->f.icu.f_delhndl(dev, __VA_ARGS__ )
 
 /** unbind icu irq for a device */
 #define DEV_ICU_UNBIND(icu_dev, dev, irq, callback)	\
@@ -113,8 +104,6 @@
 #define DEVICU_SENDIPI(n)	error_t (n) (struct ipi_endpoint_s *endpoint)
 /** ICU device class sendipi() function type. send an ipi to specified processor. */
 typedef DEVICU_SENDIPI(devicu_sendipi_t);
-/** ICU device class sendipi() function shortcut */
-#define dev_icu_sendipi(dev, ...) (dev)->drv->f.icu.f_sendipi(__VA_ARGS__ )
 
 
 
@@ -124,8 +113,6 @@
 					     uint_fast8_t ipi_no)
 /** ICU device class setupipi() function type. setup an ipi endpoint. */
 typedef DEVICU_SETUP_IPI_EP(devicu_setup_ipi_ep_t);
-/** ICU device class setupipi() function shortcut */
-#define dev_icu_setup_ipi_ep(dev, ...) (dev)->drv->f.icu.f_setup_ipi_ep(dev, __VA_ARGS__ )
 
 
 
@@ -140,5 +127,59 @@
   devicu_setup_ipi_ep_t	*f_setup_ipi_ep;
 };
 
+
+/** ICU device class enable() function shortcut */
+static inline
+error_t dev_icu_enable(struct device_s *dev, uint_fast8_t irq,
+                       bool_t enable, reg_t flags)
+{
+    const struct dev_class_icu_s *funcs =
+        driver_class_funcs(dev->drv, device_class_icu);
+
+    return funcs->f_enable(dev, irq, enable, flags);
+}
+
+/** ICU device class sethndl() function shortcut */
+static inline
+error_t dev_icu_sethndl(struct device_s *dev, uint_fast8_t irq, dev_irq_t *hndl, void *data)
+{
+    const struct dev_class_icu_s *funcs =
+        driver_class_funcs(dev->drv, device_class_icu);
+
+    return funcs->f_sethndl(dev, irq, hndl, data);
+}
+
+/** ICU device class delhndl() function shortcut */
+static inline
+error_t dev_icu_delhndl(struct device_s *dev, uint_fast8_t irq, dev_irq_t *hndl)
+{
+    const struct dev_class_icu_s *funcs =
+        driver_class_funcs(dev->drv, device_class_icu);
+
+    return funcs->f_delhndl(dev, irq, hndl);
+}
+
+/** ICU device class sendipi() function shortcut */
+static inline
+error_t dev_icu_sendipi(struct device_s *dev, struct ipi_endpoint_s *endpoint)
+{
+    const struct dev_class_icu_s *funcs =
+        driver_class_funcs(dev->drv, device_class_icu);
+
+    return funcs->f_sendipi(endpoint);
+}
+
+/** ICU device class setupipi() function shortcut */
+static inline
+error_t dev_icu_setup_ipi_ep(struct device_s *dev,
+                             struct ipi_endpoint_s *endpoint,
+                             uint_fast8_t ipi_no)
+{
+    const struct dev_class_icu_s *funcs =
+        driver_class_funcs(dev->drv, device_class_icu);
+
+    return funcs->f_setup_ipi_ep(dev, endpoint, ipi_no);
+}
+
 #endif
 
Index: drivers/include/device/net.h
===================================================================
--- drivers/include/device/net.h	(revision 1735)
+++ drivers/include/device/net.h	(working copy)
@@ -28,14 +28,12 @@
 #ifndef __DEVICE_NET_H__
 #define __DEVICE_NET_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 #include <device/device.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 struct net_packet_s;
@@ -59,8 +57,6 @@
 */
 typedef DEVNET_PREPAREPKT(devnet_preparepkt_t);
 
-/** Network device class preparepkt() method shortcut */
-#define dev_net_preparepkt(dev, ...) (dev)->drv->f.net.f_preparepkt(dev, __VA_ARGS__ )
 
 
 /** Network device class packet sending function tempate. */
@@ -76,8 +72,6 @@
 */
 typedef DEVNET_SENDPKT(devnet_sendpkt_t);
 
-/** Network device class sendpkt() method shortcut */
-#define dev_net_sendpkt(dev, ...) (dev)->drv->f.net.f_sendpkt(dev, __VA_ARGS__ )
 
 
 /** Network device class device set option function tempate. */
@@ -95,8 +89,6 @@
 */
 typedef DEVNET_SETOPT(devnet_setopt_t);
 
-/** Network device class setopt() method shortcut */
-#define dev_net_setopt(dev, ...) (dev)->drv->f.net.f_setopt(dev, __VA_ARGS__ )
 
 
 /** Network device class device get option function tempate. */
@@ -114,8 +106,6 @@
 */
 typedef DEVNET_GETOPT(devnet_getopt_t);
 
-/** Network device class getopt() method shortcut */
-#define dev_net_getopt(dev, ...) (dev)->drv->f.net.f_getopt(dev, __VA_ARGS__ )
 
 
 /** Net device class methodes */
@@ -127,5 +117,45 @@
   devnet_getopt_t		*f_getopt;
 };
 
+/** Network device class preparepkt() method shortcut */
+static inline
+uint8_t *dev_net_preparepkt(struct device_s *dev, struct net_packet_s *packet, size_t size, size_t max_padding)
+{
+    const struct dev_class_net_s *funcs =
+        driver_class_funcs(dev->drv, device_class_net);
+
+    return funcs->f_preparepkt(dev, packet, size, max_padding);
+}
+
+/** Network device class sendpkt() method shortcut */
+static inline
+void dev_net_sendpkt(struct device_s *dev, struct net_packet_s *packet, uint_fast16_t proto)
+{
+    const struct dev_class_net_s *funcs =
+        driver_class_funcs(dev->drv, device_class_net);
+
+    return funcs->f_sendpkt(dev, packet, proto);
+}
+
+/** Network device class setopt() method shortcut */
+static inline
+error_t dev_net_setopt(struct device_s *dev, uint_fast32_t option, void *value, size_t len)
+{
+    const struct dev_class_net_s *funcs =
+        driver_class_funcs(dev->drv, device_class_net);
+
+    return funcs->f_setopt(dev, option, value, len);
+}
+
+/** Network device class getopt() method shortcut */
+static inline
+error_t dev_net_getopt(struct device_s *dev, uint_fast32_t option, void *value, size_t *len)
+{
+    const struct dev_class_net_s *funcs =
+        driver_class_funcs(dev->drv, device_class_net);
+
+    return funcs->f_getopt(dev, option, value, len);
+}
+
 #endif
 
Index: drivers/include/device/fb.h
===================================================================
--- drivers/include/device/fb.h	(revision 1735)
+++ drivers/include/device/fb.h	(working copy)
@@ -28,13 +28,11 @@
 #ifndef __DEVICE_FB_H__
 #define __DEVICE_FB_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -73,12 +71,9 @@
 */
 typedef DEVFB_SETMODE(devfb_setmode_t);
 
-/** Fb device class setmode() methode shortcut */
-#define dev_fb_setmode(dev, ...) (dev)->drv->f.fb.f_setmode(dev, __VA_ARGS__ )
 
 
 
-
 /** Fb device class getbuffer() function tempate. */
 #define DEVFB_GETBUFFER(n)	uintptr_t  (n) (struct device_s *dev, uint_fast8_t page)
 
@@ -92,8 +87,6 @@
 */
 typedef DEVFB_GETBUFFER(devfb_getbuffer_t);
 
-/** Fb device class getbuffer() methode shortcut */
-#define dev_fb_getbuffer(dev, ...) (dev)->drv->f.fb.f_getbuffer(dev, __VA_ARGS__ )
 
 
 
@@ -110,8 +103,6 @@
 */
 typedef DEVFB_FLIPPAGE(devfb_flippage_t);
 
-/** Fb device class flippage() methode shortcut */
-#define dev_fb_flippage(dev, ...) (dev)->drv->f.fb.f_flippage(dev, __VA_ARGS__ )
 
 
 
@@ -129,8 +120,6 @@
 */
 typedef DEVFB_SETPALETTE(devfb_setpalette_t);
 
-/** Fb device class setpalette() methode shortcut */
-#define dev_fb_setpalette(dev, ...) (dev)->drv->f.fb.f_setpalette(dev, __VA_ARGS__ )
 
 
 /** Fb device class methodes */
@@ -143,5 +132,48 @@
 };
 
 
+/** Fb device class setmode() methode shortcut */
+static inline
+error_t dev_fb_setmode(
+  struct device_s *dev,
+  uint_fast16_t xres, uint_fast16_t yres,
+  uint_fast8_t bpp, uint_fast8_t packing)
+{
+    const struct dev_class_fb_s *funcs =
+        driver_class_funcs(dev->drv, device_class_fb);
+
+    return funcs->f_setmode(dev, xres, yres, bpp, packing);
+}
+
+/** Fb device class getbuffer() methode shortcut */
+static inline
+uintptr_t dev_fb_getbuffer(struct device_s *dev, uint_fast8_t page)
+{
+    const struct dev_class_fb_s *funcs =
+        driver_class_funcs(dev->drv, device_class_fb);
+
+    return funcs->f_getbuffer(dev, page);
+}
+
+/** Fb device class flippage() methode shortcut */
+static inline
+error_t dev_fb_flippage(struct device_s *dev, uint_fast8_t page)
+{
+    const struct dev_class_fb_s *funcs =
+        driver_class_funcs(dev->drv, device_class_fb);
+
+    return funcs->f_flippage(dev, page);
+}
+
+/** Fb device class setpalette() methode shortcut */
+static inline
+void dev_fb_setpalette(struct device_s *dev, struct fb_pal_s *pal, size_t count)
+{
+    const struct dev_class_fb_s *funcs =
+        driver_class_funcs(dev->drv, device_class_fb);
+
+    return funcs->f_setpalette(dev, pal, count);
+}
+
 #endif
 
Index: drivers/include/device/driver_fw.h
===================================================================
--- drivers/include/device/driver_fw.h	(revision 0)
+++ drivers/include/device/driver_fw.h	(revision 0)
@@ -0,0 +1,45 @@
+/*
+    This file is part of MutekH.
+
+    MutekH 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.
+
+    MutekH 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 MutekH; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+    Copyright (c) 2006-2010, MutekH contributors
+*/
+
+/**                                                                 
+ * @file                                                            
+ * @module{Device drivers}
+ * @short Driver forward definitions
+ */                                                                 
+
+#ifndef __DRIVER_FW_H__
+#define __DRIVER_FW_H__
+
+#ifdef __DRIVER_H__
+# error This header must not be included after "device/driver.h"
+#endif
+
+#include <device/device.h>
+#include <hexo/types.h>
+
+struct driver_s;
+enum device_class_e;
+
+static inline
+const void *driver_class_funcs(
+    const struct driver_s *drv,
+    enum device_class_e class);
+
+#endif

Property changes on: drivers/include/device/driver_fw.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + "Author Date Id Rev URL Revision"
Added: svn:eol-style
   + native

Index: drivers/include/device/sound.h
===================================================================
--- drivers/include/device/sound.h	(revision 1735)
+++ drivers/include/device/sound.h	(working copy)
@@ -28,13 +28,11 @@
 #ifndef __DEVICE_SOUND_H__
 #define __DEVICE_SOUND_H__
 
-#ifdef __DRIVER_H__
-# error This header must not be included after "device/driver.h"
-#endif
-
 #include <hexo/types.h>
 #include <hexo/error.h>
 
+#include <device/driver_fw.h>
+
 struct device_s;
 struct driver_s;
 
@@ -45,9 +43,6 @@
 #define DEVSOUND_READ(n)	ssize_t  (n) (struct device_s *dev, uint8_t *data, size_t count, \
 					      devsound_callback_t *cback, void *priv)
 
-/** Sound device class read() methode shortcut */
-
-#define dev_sound_read(dev, ...) (dev)->drv->f.sound.f_read(dev, __VA_ARGS__ )
 /**
    Sound device class read() function type.  Read bytes data from the
    device. Should not block if unable to read more bytes.
@@ -79,8 +74,6 @@
 */
 typedef DEVSOUND_WRITE(devsound_write_t);
 
-/** Sound device class write() methode shortcut */
-#define dev_sound_write(dev, ...) (dev)->drv->f.sound.f_write(dev, __VA_ARGS__ )
 
 
 
@@ -108,11 +101,8 @@
 */
 typedef DEVSOUND_MODE(devsound_mode_t);
 
-/** Sound device class write() methode shortcut */
-#define dev_sound_mode(dev, ...) (dev)->drv->f.sound.f_mode(dev, __VA_ARGS__ )
 
 
-
 /** Sound device class methodes */
 struct dev_class_sound_s
 {
@@ -121,6 +111,40 @@
   devsound_mode_t		*f_mode;
 };
 
+/** Sound device class read() methode shortcut */
+static inline
+ssize_t dev_sound_read(struct device_s *dev,
+                       uint8_t *data, size_t count,
+                       devsound_callback_t *cback, void *priv)
+{
+    const struct dev_class_sound_s *funcs =
+        driver_class_funcs(dev->drv, device_class_sound);
 
+    return funcs->f_read(dev, data, count, cback, priv);
+}
+
+/** Sound device class write() methode shortcut */
+static inline
+ssize_t dev_sound_write(struct device_s *dev, const uint8_t *data, size_t count,
+					      devsound_callback_t *cback, void *priv)
+{
+    const struct dev_class_sound_s *funcs =
+        driver_class_funcs(dev->drv, device_class_sound);
+
+    return funcs->f_write(dev, data, count, cback, priv);
+}
+
+/** Sound device class write() methode shortcut */
+static inline
+error_t dev_sound_mode(struct device_s *dev,
+                       enum dev_sound_mode_e mode,
+                       uint_fast8_t chan_count)
+{
+    const struct dev_class_sound_s *funcs =
+        driver_class_funcs(dev->drv, device_class_sound);
+
+    return funcs->f_mode(dev, mode, chan_count);
+}
+
 #endif
 
Index: drivers/block/soclib/block-soclib.c
===================================================================
--- drivers/block/soclib/block-soclib.c	(revision 1735)
+++ drivers/block/soclib/block-soclib.c	(working copy)
@@ -213,16 +213,23 @@
 
 const struct driver_s	block_soclib_drv =
 {
-  .class		= device_class_block,
+  .funcs_offset = {
+    [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+    [device_class_block] = 0,
+  },
   .id_table		= block_soclib_ids,
   .f_init		= block_soclib_init,
   .f_cleanup		= block_soclib_cleanup,
   .f_irq		= block_soclib_irq,
-  .f.blk = {
-    .f_request		= block_soclib_request,
-    .f_getparams	= block_soclib_getparams,
-    .f_getrqsize	= block_soclib_getrqsize,
-  }
+  .funcs = {
+    {
+      .blk = {
+        .f_request		= block_soclib_request,
+        .f_getparams	= block_soclib_getparams,
+        .f_getrqsize	= block_soclib_getrqsize,
+      },
+    },
+  },
 };
 
 REGISTER_DRIVER(block_soclib_drv);
Index: drivers/enum/root/enum-root.c
===================================================================
--- drivers/enum/root/enum-root.c	(revision 1735)
+++ drivers/enum/root/enum-root.c	(working copy)
@@ -41,12 +41,19 @@
 
 const struct driver_s	enum_root_drv =
 {
-	.class		= device_class_enum,
+    .funcs_offset = {
+        [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+        [device_class_enum] = 0,
+    },
 	.f_init		= enum_root_init,
 	.f_cleanup		= enum_root_cleanup,
-	.f.denum = {
-		.f_lookup = enum_root_lookup,
-	}
+    .funcs = {
+        {
+            .denum = {
+                .f_lookup = enum_root_lookup,
+            },
+        },
+    },
 };
 
 DEV_INIT(enum_root_init)
Index: drivers/enum/fdt/enum-fdt-initdev.c
===================================================================
--- drivers/enum/fdt/enum-fdt-initdev.c	(revision 1735)
+++ drivers/enum/fdt/enum-fdt-initdev.c	(working copy)
@@ -60,7 +60,8 @@
     struct device_s *icu = enum_fdt_lookup(enum_dev, (const char*)data);
 	dprintk("got %p\n", icu);
 
-    if ( icu->drv != NULL && icu->drv->class != device_class_icu )
+    if ( icu->drv != NULL &&
+         icu->drv->funcs_offset[device_class_icu] == DEVICE_CLASS_UNAVAILABLE )
         printk("Warning: %s is not an ICU, expect crashes\n", (const char *)data);
 	dev->icudev = icu;
 }
Index: drivers/enum/fdt/enum-fdt.c
===================================================================
--- drivers/enum/fdt/enum-fdt.c	(revision 1741)
+++ drivers/enum/fdt/enum-fdt.c	(working copy)
@@ -218,14 +218,21 @@
 
 const struct driver_s	enum_fdt_drv =
 {
-	.class		= device_class_enum,
+    .funcs_offset = {
+        [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+        [device_class_enum] = 0,
+    },
 	.f_init		= enum_fdt_init,
 	.f_cleanup		= enum_fdt_cleanup,
-	.f.denum = {
-		.f_lookup = enum_fdt_lookup,
-		.f_info = enum_fdt_info,
-//		.f_register		= enum_fdt_register,
-	}
+    .funcs = {
+        {
+            .denum = {
+                .f_lookup = enum_fdt_lookup,
+                .f_info = enum_fdt_info,
+//                .f_register		= enum_fdt_register,
+            },
+        },
+	},
 };
 
 static void *clone_blob( void *blob )
Index: drivers/char/tty-soclib/tty-soclib.c
===================================================================
--- drivers/char/tty-soclib/tty-soclib.c	(revision 1735)
+++ drivers/char/tty-soclib/tty-soclib.c	(working copy)
@@ -168,16 +168,23 @@
 
 const struct driver_s	tty_soclib_drv =
 {
-  .class		= device_class_char,
+  .funcs_offset = {
+    [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+    [device_class_char] = 0,
+  },
   .id_table		= tty_soclib_ids,
   .f_init		= tty_soclib_init,
   .f_cleanup		= tty_soclib_cleanup,
 #ifdef CONFIG_HEXO_IRQ
   .f_irq		= tty_soclib_irq,
 #endif
-  .f.chr = {
-    .f_request		= tty_soclib_request,
-  }
+  .funcs = {
+    {
+      .chr = {
+        .f_request		= tty_soclib_request,
+      },
+    },
+  },
 };
 
 REGISTER_DRIVER(tty_soclib_drv);
Index: drivers/mem/memory/memory.c
===================================================================
--- drivers/mem/memory/memory.c	(revision 1735)
+++ drivers/mem/memory/memory.c	(working copy)
@@ -50,12 +50,19 @@
 
 const struct driver_s   memory_drv =
 {
-    .class      = device_class_mem,
+    .funcs_offset = {
+        [0 ... DEVICE_CLASS_COUNT-1] = DEVICE_CLASS_UNAVAILABLE,
+        [device_class_mem] = 0,
+    },
 	.id_table	= memory_ids,
     .f_init     = memory_init,
     .f_cleanup  = memory_cleanup,
-	.f.mem = {
-		.f_get_info = memory_get_info,
+    .funcs = {
+        {
+            .mem = {
+                .f_get_info = memory_get_info,
+            },
+        },
 	},
 };
 
