diff --git a/drivers/staging/greybus/battery-gb.c b/drivers/staging/greybus/battery-gb.c index 185fa2c4b55f..74698c143bdb 100644 --- a/drivers/staging/greybus/battery-gb.c +++ b/drivers/staging/greybus/battery-gb.c @@ -359,7 +359,7 @@ static enum power_supply_property battery_props[] = { 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; @@ -397,7 +397,7 @@ int gb_battery_device_init(struct gb_connection *connection) 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; @@ -405,6 +405,11 @@ void gb_battery_device_exit(struct gb_connection *connection) 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 diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 722bee4579ea..1a849ce0ae1d 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -277,16 +277,16 @@ int gb_connection_init(struct gb_connection *connection) 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: @@ -308,28 +308,10 @@ int gb_connection_init(struct gb_connection *connection) 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); } diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h index 19dd91dae062..4492d2f67ec4 100644 --- a/drivers/staging/greybus/connection.h +++ b/drivers/staging/greybus/connection.h @@ -21,6 +21,15 @@ enum gb_connection_state { 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; @@ -38,6 +47,8 @@ struct gb_connection { 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) diff --git a/drivers/staging/greybus/gpio-gb.c b/drivers/staging/greybus/gpio-gb.c index 8781f816d968..6ba1f633a436 100644 --- a/drivers/staging/greybus/gpio-gb.c +++ b/drivers/staging/greybus/gpio-gb.c @@ -732,7 +732,7 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *gb_gpio_controlle 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; @@ -780,7 +780,7 @@ out_err: 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; @@ -792,6 +792,11 @@ void gb_gpio_controller_exit(struct gb_connection *connection) 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"); diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index deb34f1d5fbf..f907e0fe7fc9 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -266,14 +266,10 @@ void gb_deregister_cport_complete(u16 cport_id); 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); diff --git a/drivers/staging/greybus/i2c-gb.c b/drivers/staging/greybus/i2c-gb.c index e20801169b8d..5d3e2f2061b0 100644 --- a/drivers/staging/greybus/i2c-gb.c +++ b/drivers/staging/greybus/i2c-gb.c @@ -466,7 +466,7 @@ static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev) 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; @@ -509,7 +509,7 @@ out_err: 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; @@ -518,6 +518,11 @@ void gb_i2c_device_exit(struct gb_connection *connection) 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"); diff --git a/drivers/staging/greybus/uart-gb.c b/drivers/staging/greybus/uart-gb.c index 7c9229da77e4..370a78fb231f 100644 --- a/drivers/staging/greybus/uart-gb.c +++ b/drivers/staging/greybus/uart-gb.c @@ -390,7 +390,7 @@ static const struct tty_operations gb_ops = { }; -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; @@ -444,7 +444,7 @@ error: 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; @@ -524,3 +524,8 @@ static void gb_tty_exit(void) 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, +};