From 4d98098942bda347cd9b5ce1b8f253e631ddf2a8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Oct 2014 17:42:45 +0800 Subject: [PATCH] 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 -- 2.20.1