Commit 3689f974 authored by Alex Elder's avatar Alex Elder Committed by Greg Kroah-Hartman

greybus: begin abstracting connection operations

This is part 1 of abstracting the connection operations into a set
of methods.  This will avoid some big switch statements, but more
importantly this will be needed for supporting multiple versions of
each protocol.

For now only two methods are defined.  The init method is used
to set up the device (or whatever the CPort represents) and the exit
method tears it down.  There may need to be additional operations
added in the future, and once versioning is used we might stash
the version number in this structure as well.

The next patch adds dynamic registratration of these protocol
handlers, and will do away with the switch statement now found
in gb_connection_init().
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent f348964c
...@@ -359,7 +359,7 @@ static enum power_supply_property battery_props[] = { ...@@ -359,7 +359,7 @@ static enum power_supply_property battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW, 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 gb_battery *gb;
struct power_supply *b; struct power_supply *b;
...@@ -397,7 +397,7 @@ int gb_battery_device_init(struct gb_connection *connection) ...@@ -397,7 +397,7 @@ int gb_battery_device_init(struct gb_connection *connection)
return 0; 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; struct gb_battery *gb = connection->private;
...@@ -405,6 +405,11 @@ void gb_battery_device_exit(struct gb_connection *connection) ...@@ -405,6 +405,11 @@ void gb_battery_device_exit(struct gb_connection *connection)
kfree(gb); 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) void gb_battery_disconnect(struct gb_module *gmod)
{ {
#if 0 #if 0
......
...@@ -277,16 +277,16 @@ int gb_connection_init(struct gb_connection *connection) ...@@ -277,16 +277,16 @@ int gb_connection_init(struct gb_connection *connection)
connection->state = GB_CONNECTION_STATE_ENABLED; connection->state = GB_CONNECTION_STATE_ENABLED;
switch (connection->protocol) { switch (connection->protocol) {
case GREYBUS_PROTOCOL_I2C: case GREYBUS_PROTOCOL_I2C:
ret = gb_i2c_device_init(connection); connection->handler = &gb_i2c_connection_handler;
break; break;
case GREYBUS_PROTOCOL_GPIO: case GREYBUS_PROTOCOL_GPIO:
ret = gb_gpio_controller_init(connection); connection->handler = &gb_gpio_connection_handler;
break; break;
case GREYBUS_PROTOCOL_BATTERY: case GREYBUS_PROTOCOL_BATTERY:
ret = gb_battery_device_init(connection); connection->handler = &gb_battery_connection_handler;
break; break;
case GREYBUS_PROTOCOL_UART: case GREYBUS_PROTOCOL_UART:
ret = gb_uart_device_init(connection); connection->handler = &gb_uart_connection_handler;
break; break;
case GREYBUS_PROTOCOL_CONTROL: case GREYBUS_PROTOCOL_CONTROL:
case GREYBUS_PROTOCOL_AP: case GREYBUS_PROTOCOL_AP:
...@@ -308,28 +308,10 @@ int gb_connection_init(struct gb_connection *connection) ...@@ -308,28 +308,10 @@ int gb_connection_init(struct gb_connection *connection)
void gb_connection_exit(struct gb_connection *connection) void gb_connection_exit(struct gb_connection *connection)
{ {
connection->state = GB_CONNECTION_STATE_DESTROYING; if (!connection->handler) {
gb_connection_err(connection, "uninitialized connection");
switch (connection->protocol) { return;
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;
} }
connection->state = GB_CONNECTION_STATE_DESTROYING;
connection->handler->connection_exit(connection);
} }
...@@ -21,6 +21,15 @@ enum gb_connection_state { ...@@ -21,6 +21,15 @@ enum gb_connection_state {
GB_CONNECTION_STATE_DESTROYING = 4, 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 gb_connection {
struct greybus_host_device *hd; struct greybus_host_device *hd;
struct gb_interface *interface; struct gb_interface *interface;
...@@ -38,6 +47,8 @@ struct gb_connection { ...@@ -38,6 +47,8 @@ struct gb_connection {
atomic_t op_cycle; atomic_t op_cycle;
struct delayed_work timeout_work; struct delayed_work timeout_work;
struct gb_connection_handler *handler;
void *private; void *private;
}; };
#define to_gb_connection(d) container_of(d, struct gb_connection, dev) #define to_gb_connection(d) container_of(d, struct gb_connection, dev)
......
...@@ -732,7 +732,7 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *gb_gpio_controlle ...@@ -732,7 +732,7 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *gb_gpio_controlle
return ret; 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 gb_gpio_controller *gb_gpio_controller;
struct gpio_chip *gpio; struct gpio_chip *gpio;
...@@ -780,7 +780,7 @@ int gb_gpio_controller_init(struct gb_connection *connection) ...@@ -780,7 +780,7 @@ int gb_gpio_controller_init(struct gb_connection *connection)
return ret; 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; struct gb_gpio_controller *gb_gpio_controller = connection->private;
...@@ -792,6 +792,11 @@ void gb_gpio_controller_exit(struct gb_connection *connection) ...@@ -792,6 +792,11 @@ void gb_gpio_controller_exit(struct gb_connection *connection)
kfree(gb_gpio_controller); 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 #if 0
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Greybus GPIO driver"); MODULE_DESCRIPTION("Greybus GPIO driver");
......
...@@ -266,14 +266,10 @@ void gb_deregister_cport_complete(u16 cport_id); ...@@ -266,14 +266,10 @@ void gb_deregister_cport_complete(u16 cport_id);
extern struct bus_type greybus_bus_type; extern struct bus_type greybus_bus_type;
extern const struct attribute_group *greybus_module_groups[]; extern const struct attribute_group *greybus_module_groups[];
int gb_i2c_device_init(struct gb_connection *connection); extern struct gb_connection_handler gb_i2c_connection_handler;
void gb_i2c_device_exit(struct gb_connection *connection); extern struct gb_connection_handler gb_gpio_connection_handler;
extern struct gb_connection_handler gb_battery_connection_handler;
int gb_battery_device_init(struct gb_connection *connection); extern struct gb_connection_handler gb_uart_connection_handler;
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);
int gb_uart_device_init(struct gb_connection *connection); int gb_uart_device_init(struct gb_connection *connection);
void gb_uart_device_exit(struct gb_connection *connection); void gb_uart_device_exit(struct gb_connection *connection);
......
...@@ -466,7 +466,7 @@ static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev) ...@@ -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); 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 gb_i2c_device *gb_i2c_dev;
struct i2c_adapter *adapter; struct i2c_adapter *adapter;
...@@ -509,7 +509,7 @@ int gb_i2c_device_init(struct gb_connection *connection) ...@@ -509,7 +509,7 @@ int gb_i2c_device_init(struct gb_connection *connection)
return ret; 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; struct gb_i2c_device *gb_i2c_dev = connection->private;
...@@ -518,6 +518,11 @@ void gb_i2c_device_exit(struct gb_connection *connection) ...@@ -518,6 +518,11 @@ void gb_i2c_device_exit(struct gb_connection *connection)
kfree(gb_i2c_dev); 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 #if 0
module_greybus_driver(i2c_gb_driver); module_greybus_driver(i2c_gb_driver);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -390,7 +390,7 @@ static const struct tty_operations gb_ops = { ...@@ -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 gb_tty *gb_tty;
struct device *tty_dev; struct device *tty_dev;
...@@ -444,7 +444,7 @@ int gb_uart_device_init(struct gb_connection *connection) ...@@ -444,7 +444,7 @@ int gb_uart_device_init(struct gb_connection *connection)
return retval; 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 gb_tty *gb_tty = connection->private;
struct tty_struct *tty; struct tty_struct *tty;
...@@ -524,3 +524,8 @@ static void gb_tty_exit(void) ...@@ -524,3 +524,8 @@ static void gb_tty_exit(void)
put_tty_driver(gb_tty_driver); put_tty_driver(gb_tty_driver);
unregister_chrdev_region(MKDEV(major, minor), GB_NUM_MINORS); 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,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment