From 81d631cae83e32e3dcab0d20d9c387592e1fa230 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 27 Oct 2014 03:48:31 -0500 Subject: [PATCH 01/11] greybus: gpio: kill gpio_controller->gpio This field is never used (and not needed) so get rid of it. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/gpio-gb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/greybus/gpio-gb.c b/drivers/staging/greybus/gpio-gb.c index 069ee69dc0e7..8781f816d968 100644 --- a/drivers/staging/greybus/gpio-gb.c +++ b/drivers/staging/greybus/gpio-gb.c @@ -29,7 +29,6 @@ struct gb_gpio_controller { struct gb_gpio_line *lines; struct gpio_chip chip; - struct gpio_chip *gpio; }; #define gpio_chip_to_gb_gpio_controller(chip) \ container_of(chip, struct gb_gpio_controller, chip) From 81f4e22732f0a29826168899d7e62839812d34dd Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 27 Oct 2014 03:48:32 -0500 Subject: [PATCH 02/11] greybus: embed the i2c adapter struct We don't need to dynamically allocate the i2c adapter structure, we can just embed it right in struct gb_i2c_device. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/i2c-gb.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/staging/greybus/i2c-gb.c b/drivers/staging/greybus/i2c-gb.c index 9ecfd795ea84..e20801169b8d 100644 --- a/drivers/staging/greybus/i2c-gb.c +++ b/drivers/staging/greybus/i2c-gb.c @@ -22,7 +22,7 @@ struct gb_i2c_device { u16 timeout_msec; u8 retries; - struct i2c_adapter *adapter; + struct i2c_adapter adapter; }; /* Version of the Greybus i2c protocol we support */ @@ -469,7 +469,7 @@ static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev) int gb_i2c_device_init(struct gb_connection *connection) { struct gb_i2c_device *gb_i2c_dev; - struct i2c_adapter *adapter = NULL; + struct i2c_adapter *adapter; int ret; gb_i2c_dev = kzalloc(sizeof(*gb_i2c_dev), GFP_KERNEL); @@ -482,13 +482,8 @@ int gb_i2c_device_init(struct gb_connection *connection) if (ret) goto out_err; - /* Looks good; allocate and set up our i2c adapter */ - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); - if (!adapter) { - ret = -ENOMEM; - goto out_err; - } - + /* Looks good; up our i2c adapter */ + adapter = &gb_i2c_dev->adapter; adapter->owner = THIS_MODULE; adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adapter->algo = &gb_i2c_algorithm; @@ -504,12 +499,10 @@ int gb_i2c_device_init(struct gb_connection *connection) if (ret) goto out_err; - gb_i2c_dev->adapter = adapter; connection->private = gb_i2c_dev; return 0; out_err: - kfree(adapter); /* kref_put(gb_i2c_dev->connection) */ kfree(gb_i2c_dev); @@ -520,8 +513,7 @@ void gb_i2c_device_exit(struct gb_connection *connection) { struct gb_i2c_device *gb_i2c_dev = connection->private; - i2c_del_adapter(gb_i2c_dev->adapter); - kfree(gb_i2c_dev->adapter); + i2c_del_adapter(&gb_i2c_dev->adapter); /* kref_put(gb_i2c_dev->connection) */ kfree(gb_i2c_dev); } From aed0bc6e6856d467061e8de2f3adc713c3561628 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Oct 2014 17:32:34 +0800 Subject: [PATCH 03/11] greybus: uart-gb: convert over to the connection interface Move the uart code over to use the "new" connection interface, instead of the "old" module interface. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/connection.c | 8 ++++++-- drivers/staging/greybus/greybus.h | 3 +++ drivers/staging/greybus/uart-gb.c | 29 ++++++++++------------------ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 2d71679ff66c..2d3421f6aa10 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -285,9 +285,11 @@ int gb_connection_init(struct gb_connection *connection) case GREYBUS_PROTOCOL_BATTERY: ret = gb_battery_device_init(connection); break; + case GREYBUS_PROTOCOL_UART: + ret = gb_uart_device_init(connection); + break; case GREYBUS_PROTOCOL_CONTROL: case GREYBUS_PROTOCOL_AP: - case GREYBUS_PROTOCOL_UART: case GREYBUS_PROTOCOL_HID: case GREYBUS_PROTOCOL_LED: case GREYBUS_PROTOCOL_VENDOR: @@ -318,9 +320,11 @@ void gb_connection_exit(struct gb_connection *connection) 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_UART: case GREYBUS_PROTOCOL_HID: case GREYBUS_PROTOCOL_VENDOR: default: diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index 1e3f31d4a058..c700b0d78a10 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -275,6 +275,9 @@ 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); +void gb_uart_device_exit(struct gb_connection *connection); + int gb_tty_init(void); void gb_tty_exit(void); diff --git a/drivers/staging/greybus/uart-gb.c b/drivers/staging/greybus/uart-gb.c index 301868cd5878..d15a49b3b11d 100644 --- a/drivers/staging/greybus/uart-gb.c +++ b/drivers/staging/greybus/uart-gb.c @@ -35,7 +35,7 @@ struct gb_tty { struct tty_port port; - struct gb_module *gmod; + struct gb_connection *connection; u16 cport_id; unsigned int minor; unsigned char clocal; @@ -386,8 +386,7 @@ static const struct tty_operations gb_ops = { }; -int gb_tty_probe(struct gb_module *gmod, - const struct greybus_module_id *id) +int gb_uart_device_init(struct gb_connection *connection) { struct gb_tty *gb_tty; struct device *tty_dev; @@ -401,14 +400,14 @@ int gb_tty_probe(struct gb_module *gmod, minor = alloc_minor(gb_tty); if (minor < 0) { if (minor == -ENOSPC) { - dev_err(&gmod->dev, "no more free minor numbers\n"); + dev_err(&connection->dev, "no more free minor numbers\n"); return -ENODEV; } return minor; } gb_tty->minor = minor; - gb_tty->gmod = gmod; + gb_tty->connection = connection; spin_lock_init(&gb_tty->write_lock); spin_lock_init(&gb_tty->read_lock); init_waitqueue_head(&gb_tty->wioctl); @@ -416,10 +415,10 @@ int gb_tty_probe(struct gb_module *gmod, /* FIXME - allocate gb buffers */ - gmod->gb_tty = gb_tty; + connection->private = gb_tty; tty_dev = tty_port_register_device(&gb_tty->port, gb_tty_driver, minor, - &gmod->dev); + &connection->dev); if (IS_ERR(tty_dev)) { retval = PTR_ERR(tty_dev); goto error; @@ -427,14 +426,14 @@ int gb_tty_probe(struct gb_module *gmod, return 0; error: - gmod->gb_tty = NULL; + connection->private = NULL; release_minor(gb_tty); return retval; } -void gb_tty_disconnect(struct gb_module *gmod) +void gb_uart_device_exit(struct gb_connection *connection) { - struct gb_tty *gb_tty = gmod->gb_tty; + struct gb_tty *gb_tty = connection->private; struct tty_struct *tty; if (!gb_tty) @@ -444,7 +443,7 @@ void gb_tty_disconnect(struct gb_module *gmod) gb_tty->disconnected = true; wake_up_all(&gb_tty->wioctl); - gmod->gb_tty = NULL; + connection->private = NULL; mutex_unlock(&gb_tty->mutex); tty = tty_port_tty_get(&gb_tty->port); @@ -463,14 +462,6 @@ void gb_tty_disconnect(struct gb_module *gmod) kfree(gb_tty); } -#if 0 -static struct greybus_driver tty_gb_driver = { - .probe = gb_tty_probe, - .disconnect = gb_tty_disconnect, - .id_table = id_table, -}; -#endif - int __init gb_tty_init(void) { int retval = 0; From 4d98098942bda347cd9b5ce1b8f253e631ddf2a8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Oct 2014 17:42:45 +0800 Subject: [PATCH 04/11] greybus: uart-gb: remove global init functions The uart-gb code needs to init the tty core before it can add devices. Previously we hard-coded this in the greybus core, move this to be "dynamic" and self-contained within the uart-gb.c file. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/core.c | 10 -------- drivers/staging/greybus/greybus.h | 3 --- drivers/staging/greybus/uart-gb.c | 41 ++++++++++++++----------------- 3 files changed, 19 insertions(+), 35 deletions(-) diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 61fd6906541d..7c0cb6227b1f 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -282,17 +282,8 @@ static int __init gb_init(void) goto error_operation; } - retval = gb_tty_init(); - if (retval) { - pr_err("gb_tty_init failed\n"); - goto error_tty; - } - return 0; -error_tty: - gb_operation_exit(); - error_operation: gb_gbuf_exit(); @@ -310,7 +301,6 @@ error_bus: static void __exit gb_exit(void) { - gb_tty_exit(); gb_operation_exit(); gb_gbuf_exit(); gb_ap_exit(); diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index c700b0d78a10..deb34f1d5fbf 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -278,9 +278,6 @@ void gb_gpio_controller_exit(struct gb_connection *connection); int gb_uart_device_init(struct gb_connection *connection); void gb_uart_device_exit(struct gb_connection *connection); -int gb_tty_init(void); -void gb_tty_exit(void); - int svc_set_route_send(struct gb_interface *interface, struct greybus_host_device *hd); diff --git a/drivers/staging/greybus/uart-gb.c b/drivers/staging/greybus/uart-gb.c index d15a49b3b11d..7c9229da77e4 100644 --- a/drivers/staging/greybus/uart-gb.c +++ b/drivers/staging/greybus/uart-gb.c @@ -59,6 +59,10 @@ static const struct greybus_module_id id_table[] = { static struct tty_driver *gb_tty_driver; static DEFINE_IDR(tty_minors); static DEFINE_MUTEX(table_lock); +static atomic_t reference_count = ATOMIC_INIT(0); + +static int gb_tty_init(void); +static void gb_tty_exit(void); static struct gb_tty *get_gb_by_minor(unsigned minor) { @@ -393,6 +397,15 @@ int gb_uart_device_init(struct gb_connection *connection) int retval; int minor; + /* First time here, initialize the tty structures */ + if (atomic_inc_return(&reference_count) == 1) { + retval = gb_tty_init(); + if (retval) { + atomic_dec(&reference_count); + return retval; + } + } + gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL); if (!gb_tty) return -ENOMEM; @@ -460,9 +473,13 @@ void gb_uart_device_exit(struct gb_connection *connection) tty_port_put(&gb_tty->port); kfree(gb_tty); + + /* If last device is gone, tear down the tty structures */ + if (atomic_dec_return(&reference_count) == 0) + gb_tty_exit(); } -int __init gb_tty_init(void) +static int gb_tty_init(void) { int retval = 0; @@ -490,40 +507,20 @@ int __init gb_tty_init(void) goto fail_put_gb_tty; } -#if 0 - retval = greybus_register(&tty_gb_driver); - if (retval) { - pr_err("Can not register greybus driver.\n"); - goto fail_unregister_gb_tty; - } -#endif - return 0; -/* fail_unregister_gb_tty: */ - tty_unregister_driver(gb_tty_driver); fail_put_gb_tty: put_tty_driver(gb_tty_driver); fail_unregister_dev: return retval; } -void __exit gb_tty_exit(void) +static void gb_tty_exit(void) { int major = MAJOR(gb_tty_driver->major); int minor = gb_tty_driver->minor_start; -#if 0 - greybus_deregister(&tty_gb_driver); -#endif tty_unregister_driver(gb_tty_driver); put_tty_driver(gb_tty_driver); unregister_chrdev_region(MKDEV(major, minor), GB_NUM_MINORS); } - -#if 0 -module_init(gb_tty_init); -module_exit(gb_tty_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Greg Kroah-Hartman "); -#endif From 6507cced6bf00c53108034a4954b9b8b73e6a216 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Oct 2014 17:58:54 +0800 Subject: [PATCH 05/11] greybus: FIXME/XXX removals: We have proper reference counting now Now that we have proper reference counting for modules, interfaces, and connections, no need to worry about grabbing a pointer to your "parent" structure, all is good. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/battery-gb.c | 2 +- drivers/staging/greybus/connection.c | 2 +- drivers/staging/greybus/interface.c | 2 +- drivers/staging/greybus/operation.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/greybus/battery-gb.c b/drivers/staging/greybus/battery-gb.c index 592b68d5115a..185fa2c4b55f 100644 --- a/drivers/staging/greybus/battery-gb.c +++ b/drivers/staging/greybus/battery-gb.c @@ -369,7 +369,7 @@ int gb_battery_device_init(struct gb_connection *connection) if (!gb) return -ENOMEM; - gb->connection = connection; // FIXME refcount! + gb->connection = connection; connection->private = gb; /* Check the version */ diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 2d3421f6aa10..722bee4579ea 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -179,7 +179,7 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface, return NULL; } - connection->interface = interface; /* XXX refcount? */ + connection->interface = interface; connection->interface_cport_id = cport_id; connection->protocol = protocol; connection->state = GB_CONNECTION_STATE_DISABLED; diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index a7375a2809d5..163cdc439e0c 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -61,7 +61,7 @@ gb_interface_create(struct gb_module *gmod, u8 interface_id) if (!interface) return NULL; - interface->gmod = gmod; /* XXX refcount? */ + interface->gmod = gmod; interface->id = interface_id; interface->device_id = 0xff; /* Invalid device id to start with */ INIT_LIST_HEAD(&interface->connections); diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 9b889b169bf5..df3a50227625 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -349,7 +349,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection, operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags); if (!operation) return NULL; - operation->connection = connection; /* XXX refcount? */ + operation->connection = connection; operation->request = gb_operation_gbuf_create(operation, type, request_size, From eec5883f5179367821ab5102be897231dc64fa62 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Oct 2014 18:00:13 +0800 Subject: [PATCH 06/11] greybus: module: remove unneeded XXX comment about module id values We do properly check for duplicate module ids, as fixed in 008d85d90ae1ab31f1f7b80f245f6ee2eb5aed49 "module: don't create duplicate module ids", so remove the XXX marker. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/greybus/module.c b/drivers/staging/greybus/module.c index 54e8f9e68d25..f65aea680be7 100644 --- a/drivers/staging/greybus/module.c +++ b/drivers/staging/greybus/module.c @@ -82,7 +82,7 @@ struct gb_module *gb_module_create(struct greybus_host_device *hd, u8 module_id) return NULL; gmod->hd = hd; /* XXX refcount? */ - gmod->module_id = module_id; /* XXX check for dups */ + gmod->module_id = module_id; INIT_LIST_HEAD(&gmod->interfaces); spin_lock_irq(&gb_modules_lock); From f348964c266c6b2db80af8b7a75a6f9ef566f1c3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 28 Oct 2014 09:27:50 +0800 Subject: [PATCH 07/11] greybus: kernel_ver.h: add ATTRIBUTE_GROUPS() macro for older kernels This was added in 3.11, and we need it for 3.10 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/kernel_ver.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/staging/greybus/kernel_ver.h b/drivers/staging/greybus/kernel_ver.h index e0fea182c3b5..e4cda5ce65fa 100644 --- a/drivers/staging/greybus/kernel_ver.h +++ b/drivers/staging/greybus/kernel_ver.h @@ -48,4 +48,19 @@ static inline void gb_gpiochip_remove(struct gpio_chip *chip) } #endif +/* + * ATTRIBUTE_GROUPS showed up in 3.11-rc2, but we need to build on 3.10, so add + * it here. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) +#define ATTRIBUTE_GROUPS(name) \ +static const struct attribute_group name##_group = { \ + .attrs = name##_attrs, \ +}; \ +static const struct attribute_group *name##_groups[] = { \ + &name##_group, \ + NULL, \ +} +#endif + #endif /* __GREYBUS_KERNEL_VER_H */ From 3689f9744a029ee9b7b38fb177249d2812ffa676 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 27 Oct 2014 06:04:30 -0500 Subject: [PATCH 08/11] 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: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/battery-gb.c | 9 +++++-- drivers/staging/greybus/connection.c | 36 +++++++--------------------- drivers/staging/greybus/connection.h | 11 +++++++++ drivers/staging/greybus/gpio-gb.c | 9 +++++-- drivers/staging/greybus/greybus.h | 12 ++++------ drivers/staging/greybus/i2c-gb.c | 9 +++++-- drivers/staging/greybus/uart-gb.c | 9 +++++-- 7 files changed, 52 insertions(+), 43 deletions(-) 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, +}; From 059b093616313683a3d6259646d21f64d2756838 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 28 Oct 2014 09:49:33 +0800 Subject: [PATCH 09/11] greybus: uart-gb: mark some functions static Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/uart-gb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/greybus/uart-gb.c b/drivers/staging/greybus/uart-gb.c index 370a78fb231f..f88a301eb9fe 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_connection_init(struct gb_connection *connection) +static 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_connection_exit(struct gb_connection *connection) +static void gb_uart_connection_exit(struct gb_connection *connection) { struct gb_tty *gb_tty = connection->private; struct tty_struct *tty; From 5e8e8ff6d0bf804e1f85154f21bcca699e2f8aa9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 28 Oct 2014 09:50:56 +0800 Subject: [PATCH 10/11] greybus: battery-gb: remove some #if 0 code We aren't going to have individual modules for the gb protocols, so just remove this useless code, it was throwing up warnings in sparse. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/battery-gb.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/staging/greybus/battery-gb.c b/drivers/staging/greybus/battery-gb.c index 74698c143bdb..b7d8e2c8fb85 100644 --- a/drivers/staging/greybus/battery-gb.c +++ b/drivers/staging/greybus/battery-gb.c @@ -409,30 +409,3 @@ 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 - struct gb_battery *gb; - - gb = gmod->gb_battery; - if (!gb) - return; - - power_supply_unregister(&gb->bat); - - kfree(gb); -#endif -} - -#if 0 -static struct greybus_driver battery_gb_driver = { - .probe = gb_battery_probe, - .disconnect = gb_battery_disconnect, - .id_table = id_table, -}; - -module_greybus_driver(battery_gb_driver); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Greg Kroah-Hartman "); -#endif From a2f4763f4829c5efb9e38b9d25385d464e0e277a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 28 Oct 2014 10:17:09 +0800 Subject: [PATCH 11/11] greybus: sdio-gb: convert to the connection interface. No one is using sdio yet, but convert to the connection interface to remove the last user of the "old" module interface. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/greybus.h | 2 +- drivers/staging/greybus/sdio-gb.c | 31 ++++++++++++------------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index f907e0fe7fc9..3a8d8f1c077c 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -151,7 +151,6 @@ struct gbuf { struct gb_i2c_device; struct gb_gpio_device; -struct gb_sdio_host; struct gb_tty; struct gb_usb_device; struct gb_battery; @@ -270,6 +269,7 @@ 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; +extern struct gb_connection_handler gb_sdio_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/sdio-gb.c b/drivers/staging/greybus/sdio-gb.c index 19c7c4ac81eb..e9c311780556 100644 --- a/drivers/staging/greybus/sdio-gb.c +++ b/drivers/staging/greybus/sdio-gb.c @@ -13,6 +13,7 @@ #include "greybus.h" struct gb_sdio_host { + struct gb_connection *connection; struct mmc_host *mmc; struct mmc_request *mrq; // FIXME - some lock? @@ -45,13 +46,12 @@ static const struct mmc_host_ops gb_sd_ops = { .get_ro = gb_sd_get_ro, }; -int gb_sdio_probe(struct gb_module *gmod, - const struct greybus_module_id *id) +static int gb_sdio_connection_init(struct gb_connection *connection) { struct mmc_host *mmc; struct gb_sdio_host *host; - mmc = mmc_alloc_host(sizeof(struct gb_sdio_host), &gmod->dev); + mmc = mmc_alloc_host(sizeof(struct gb_sdio_host), &connection->dev); if (!mmc) return -ENOMEM; @@ -60,36 +60,29 @@ int gb_sdio_probe(struct gb_module *gmod, mmc->ops = &gb_sd_ops; // FIXME - set up size limits we can handle. + // FIXME - register the host controller. - // gmod->gb_sdio_host = host; + host->connection = connection; + connection->private = host; return 0; } -void gb_sdio_disconnect(struct gb_module *gmod) +static void gb_sdio_connection_exit(struct gb_connection *connection) { -#if 0 struct mmc_host *mmc; struct gb_sdio_host *host; - host = gmod->gb_sdio_host; + host = connection->private; if (!host) return; mmc = host->mmc; mmc_remove_host(mmc); mmc_free_host(mmc); -#endif + connection->private = NULL; } -#if 0 -static struct greybus_driver sd_gb_driver = { - .probe = gb_sdio_probe, - .disconnect = gb_sdio_disconnect, - .id_table = id_table, +struct gb_connection_handler gb_sdio_connection_handler = { + .connection_init = gb_sdio_connection_init, + .connection_exit = gb_sdio_connection_exit, }; - -module_greybus_driver(sd_gb_driver); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Greybus SD/MMC Host driver"); -MODULE_AUTHOR("Greg Kroah-Hartman "); -#endif