From: Alex Elder Date: Fri, 12 Jun 2015 15:21:08 +0000 (-0500) Subject: greybus: connection: un-abstract host cport id allocation X-Git-Tag: v4.9-rc1~119^2~378^2~21^2~1468 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=f9b0366f16c3926e92e7d108fe8666fac671d026;p=karo-tx-linux.git greybus: connection: un-abstract host cport id allocation I did this recently for the endo id allocation code. It's clearer now that the allocation of a CPort ID to use for the AP side of a connection is not very complicated, and it happens in a pretty controlled environment. The functions that abstract getting and releasing those ids don't really add that much value. This patch removes gb_connection_hd_cport_id_alloc() and gb_connection_hd_cport_id_free(), and just open-codes their activity in the few places they are called. It is obvious now that the CPort ID allocation isn't done in atomic context, so we can change the ida_simple_get() call to use GFP_KERNEL. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index abd74116cf62..7236e47ea9c8 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -59,39 +59,6 @@ void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id, } EXPORT_SYMBOL_GPL(greybus_data_rcvd); -/* - * Allocate an available CPort Id for use for the host side of the - * given connection. The lowest-available id is returned, so the - * first call is guaranteed to allocate CPort Id 0. - * - * Assigns the connection's hd_cport_id and returns true if successful. - * Returns false otherwise. - */ -static bool gb_connection_hd_cport_id_alloc(struct gb_connection *connection) -{ - struct ida *ida = &connection->hd->cport_id_map; - int id; - - id = ida_simple_get(ida, 0, HOST_DEV_CPORT_ID_MAX, GFP_ATOMIC); - if (id < 0) - return false; - - connection->hd_cport_id = (u16)id; - - return true; -} - -/* - * Free a previously-allocated CPort Id on the given host device. - */ -static void gb_connection_hd_cport_id_free(struct gb_connection *connection) -{ - struct ida *ida = &connection->hd->cport_id_map; - - ida_simple_remove(ida, connection->hd_cport_id); - connection->hd_cport_id = CPORT_ID_BAD; -} - static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -172,6 +139,7 @@ struct gb_connection *gb_connection_create(struct gb_bundle *bundle, { struct gb_connection *connection; struct greybus_host_device *hd = bundle->intf->hd; + struct ida *id_map = &hd->cport_id_map; int retval; u8 major = 0; u8 minor = 1; @@ -190,17 +158,20 @@ struct gb_connection *gb_connection_create(struct gb_bundle *bundle, if (!connection) return NULL; + retval = ida_simple_get(id_map, 0, HOST_DEV_CPORT_ID_MAX, GFP_KERNEL); + if (retval < 0) { + kfree(connection); + return NULL; + } + connection->hd_cport_id = (u16)retval; + connection->intf_cport_id = cport_id; connection->hd = hd; + connection->protocol_id = protocol_id; connection->major = major; connection->minor = minor; - if (!gb_connection_hd_cport_id_alloc(connection)) { - kfree(connection); - return NULL; - } connection->bundle = bundle; - connection->intf_cport_id = cport_id; connection->state = GB_CONNECTION_STATE_DISABLED; connection->dev.parent = &bundle->dev; @@ -213,10 +184,14 @@ struct gb_connection *gb_connection_create(struct gb_bundle *bundle, retval = device_add(&connection->dev); if (retval) { + struct ida *id_map = &connection->hd->cport_id_map; + + ida_simple_remove(id_map, connection->hd_cport_id); + connection->hd_cport_id = CPORT_ID_BAD; + put_device(&connection->dev); + pr_err("failed to add connection device for cport 0x%04hx\n", cport_id); - gb_connection_hd_cport_id_free(connection); - put_device(&connection->dev); return NULL; } @@ -245,6 +220,7 @@ void gb_connection_destroy(struct gb_connection *connection) { struct gb_operation *operation; struct gb_operation *next; + struct ida *id_map; if (WARN_ON(!connection)) return; @@ -260,10 +236,13 @@ void gb_connection_destroy(struct gb_connection *connection) list_del(&connection->hd_links); spin_unlock_irq(&gb_connections_lock); - gb_connection_hd_cport_id_free(connection); gb_protocol_put(connection->protocol); connection->protocol = NULL; + id_map = &connection->hd->cport_id_map; + ida_simple_remove(id_map, connection->hd_cport_id); + connection->hd_cport_id = CPORT_ID_BAD; + device_unregister(&connection->dev); }