POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
-int gb_battery_device_init(struct gb_connection *connection)
+static int gb_battery_connection_init(struct gb_connection *connection)
 {
        struct gb_battery *gb;
        struct power_supply *b;
        return 0;
 }
 
-void gb_battery_device_exit(struct gb_connection *connection)
+static void gb_battery_connection_exit(struct gb_connection *connection)
 {
        struct gb_battery *gb = connection->private;
 
        kfree(gb);
 }
 
+struct gb_connection_handler gb_battery_connection_handler = {
+       .connection_init        = gb_battery_connection_init,
+       .connection_exit        = gb_battery_connection_exit,
+};
+
 void gb_battery_disconnect(struct gb_module *gmod)
 {
 #if 0
 
        connection->state = GB_CONNECTION_STATE_ENABLED;
        switch (connection->protocol) {
        case GREYBUS_PROTOCOL_I2C:
-               ret = gb_i2c_device_init(connection);
+               connection->handler = &gb_i2c_connection_handler;
                break;
        case GREYBUS_PROTOCOL_GPIO:
-               ret = gb_gpio_controller_init(connection);
+               connection->handler = &gb_gpio_connection_handler;
                break;
        case GREYBUS_PROTOCOL_BATTERY:
-               ret = gb_battery_device_init(connection);
+               connection->handler = &gb_battery_connection_handler;
                break;
        case GREYBUS_PROTOCOL_UART:
-               ret = gb_uart_device_init(connection);
+               connection->handler = &gb_uart_connection_handler;
                break;
        case GREYBUS_PROTOCOL_CONTROL:
        case GREYBUS_PROTOCOL_AP:
 
 void gb_connection_exit(struct gb_connection *connection)
 {
-       connection->state = GB_CONNECTION_STATE_DESTROYING;
-
-       switch (connection->protocol) {
-       case GREYBUS_PROTOCOL_I2C:
-               gb_i2c_device_exit(connection);
-               break;
-       case GREYBUS_PROTOCOL_GPIO:
-               gb_gpio_controller_exit(connection);
-               break;
-       case GREYBUS_PROTOCOL_BATTERY:
-               gb_battery_device_exit(connection);
-               break;
-       case GREYBUS_PROTOCOL_UART:
-               gb_uart_device_exit(connection);
-               break;
-       case GREYBUS_PROTOCOL_CONTROL:
-       case GREYBUS_PROTOCOL_AP:
-       case GREYBUS_PROTOCOL_HID:
-       case GREYBUS_PROTOCOL_VENDOR:
-       default:
-               gb_connection_err(connection, "unimplemented protocol %u",
-                       (u32)connection->protocol);
-               break;
+       if (!connection->handler) {
+               gb_connection_err(connection, "uninitialized connection");
+               return;
        }
+       connection->state = GB_CONNECTION_STATE_DESTROYING;
+       connection->handler->connection_exit(connection);
 }
 
        GB_CONNECTION_STATE_DESTROYING  = 4,
 };
 
+struct gb_connection;
+typedef int (*gb_connection_init_t)(struct gb_connection *);
+typedef void (*gb_connection_exit_t)(struct gb_connection *);
+
+struct gb_connection_handler {
+       gb_connection_init_t    connection_init;
+       gb_connection_exit_t    connection_exit;
+};
+
 struct gb_connection {
        struct greybus_host_device      *hd;
        struct gb_interface             *interface;
        atomic_t                        op_cycle;
        struct delayed_work             timeout_work;
 
+       struct gb_connection_handler    *handler;
+
        void                            *private;
 };
 #define to_gb_connection(d) container_of(d, struct gb_connection, dev)
 
        return ret;
 }
 
-int gb_gpio_controller_init(struct gb_connection *connection)
+static int gb_gpio_connection_init(struct gb_connection *connection)
 {
        struct gb_gpio_controller *gb_gpio_controller;
        struct gpio_chip *gpio;
        return ret;
 }
 
-void gb_gpio_controller_exit(struct gb_connection *connection)
+static void gb_gpio_connection_exit(struct gb_connection *connection)
 {
        struct gb_gpio_controller *gb_gpio_controller = connection->private;
 
        kfree(gb_gpio_controller);
 }
 
+struct gb_connection_handler gb_gpio_connection_handler = {
+       .connection_init        = gb_gpio_connection_init,
+       .connection_exit        = gb_gpio_connection_exit,
+};
+
 #if 0
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Greybus GPIO driver");
 
 extern struct bus_type greybus_bus_type;
 extern const struct attribute_group *greybus_module_groups[];
 
-int gb_i2c_device_init(struct gb_connection *connection);
-void gb_i2c_device_exit(struct gb_connection *connection);
-
-int gb_battery_device_init(struct gb_connection *connection);
-void gb_battery_device_exit(struct gb_connection *connection);
-
-int gb_gpio_controller_init(struct gb_connection *connection);
-void gb_gpio_controller_exit(struct gb_connection *connection);
+extern struct gb_connection_handler gb_i2c_connection_handler;
+extern struct gb_connection_handler gb_gpio_connection_handler;
+extern struct gb_connection_handler gb_battery_connection_handler;
+extern struct gb_connection_handler gb_uart_connection_handler;
 
 int gb_uart_device_init(struct gb_connection *connection);
 void gb_uart_device_exit(struct gb_connection *connection);
 
        return gb_i2c_timeout_operation(gb_i2c_dev, GB_I2C_TIMEOUT_DEFAULT);
 }
 
-int gb_i2c_device_init(struct gb_connection *connection)
+static int gb_i2c_connection_init(struct gb_connection *connection)
 {
        struct gb_i2c_device *gb_i2c_dev;
        struct i2c_adapter *adapter;
        return ret;
 }
 
-void gb_i2c_device_exit(struct gb_connection *connection)
+static void gb_i2c_connection_exit(struct gb_connection *connection)
 {
        struct gb_i2c_device *gb_i2c_dev = connection->private;
 
        kfree(gb_i2c_dev);
 }
 
+struct gb_connection_handler gb_i2c_connection_handler = {
+       .connection_init        = gb_i2c_connection_init,
+       .connection_exit        = gb_i2c_connection_exit,
+};
+
 #if 0
 module_greybus_driver(i2c_gb_driver);
 MODULE_LICENSE("GPL");
 
 };
 
 
-int gb_uart_device_init(struct gb_connection *connection)
+int gb_uart_connection_init(struct gb_connection *connection)
 {
        struct gb_tty *gb_tty;
        struct device *tty_dev;
        return retval;
 }
 
-void gb_uart_device_exit(struct gb_connection *connection)
+void gb_uart_connection_exit(struct gb_connection *connection)
 {
        struct gb_tty *gb_tty = connection->private;
        struct tty_struct *tty;
        put_tty_driver(gb_tty_driver);
        unregister_chrdev_region(MKDEV(major, minor), GB_NUM_MINORS);
 }
+
+struct gb_connection_handler gb_uart_connection_handler = {
+       .connection_init        = gb_uart_connection_init,
+       .connection_exit        = gb_uart_connection_exit,
+};