greybus: use a simple list of hd connections
First of all, there's a bug in _gb_hd_connection_insert, which Viresh found. But pointing out that problem just called attention to the fact that I have planning to to remove the affected block of code. The set of connections associated with a host device is currently maintained in a red-black tree. The number of connections we're likely to have is on the order of a hundred, and at least for now isn't even going to approach that. When this code first went in, Greg asserted that using a list is speedier than a red-black tree for smallish numbers of elements (maybe up to a few hundred?). So this patch just removes the host device's red-black tree of connections, using a simple list instead. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>hifive-unleashed-5.1
parent
ba99346828
commit
2c43ce4967
|
@ -13,51 +13,15 @@
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(gb_connections_lock);
|
static DEFINE_SPINLOCK(gb_connections_lock);
|
||||||
|
|
||||||
static void _gb_hd_connection_insert(struct greybus_host_device *hd,
|
|
||||||
struct gb_connection *connection)
|
|
||||||
{
|
|
||||||
struct rb_root *root = &hd->connections;
|
|
||||||
struct rb_node *node = &connection->hd_node;
|
|
||||||
struct rb_node **link = &root->rb_node;
|
|
||||||
struct rb_node *above = NULL;
|
|
||||||
u16 cport_id = connection->hd_cport_id;
|
|
||||||
|
|
||||||
while (*link) {
|
|
||||||
struct gb_connection *_connection;
|
|
||||||
|
|
||||||
above = *link;
|
|
||||||
_connection = rb_entry(above, struct gb_connection, hd_node);
|
|
||||||
if (_connection->hd_cport_id > cport_id)
|
|
||||||
link = &above->rb_left;
|
|
||||||
else if (_connection->hd_cport_id < cport_id)
|
|
||||||
link = &above->rb_right;
|
|
||||||
}
|
|
||||||
rb_link_node(node, above, link);
|
|
||||||
rb_insert_color(node, root);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _gb_hd_connection_remove(struct gb_connection *connection)
|
|
||||||
{
|
|
||||||
rb_erase(&connection->hd_node, &connection->hd->connections);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gb_connection *gb_hd_connection_find(struct greybus_host_device *hd,
|
struct gb_connection *gb_hd_connection_find(struct greybus_host_device *hd,
|
||||||
u16 cport_id)
|
u16 cport_id)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = NULL;
|
struct gb_connection *connection = NULL;
|
||||||
struct rb_node *node;
|
|
||||||
|
|
||||||
spin_lock_irq(&gb_connections_lock);
|
spin_lock_irq(&gb_connections_lock);
|
||||||
node = hd->connections.rb_node;
|
list_for_each_entry(connection, &hd->connections, hd_links)
|
||||||
while (node) {
|
if (connection->hd_cport_id == cport_id)
|
||||||
connection = rb_entry(node, struct gb_connection, hd_node);
|
|
||||||
if (connection->hd_cport_id > cport_id)
|
|
||||||
node = node->rb_left;
|
|
||||||
else if (connection->hd_cport_id < cport_id)
|
|
||||||
node = node->rb_right;
|
|
||||||
else
|
|
||||||
goto found;
|
goto found;
|
||||||
}
|
|
||||||
connection = NULL;
|
connection = NULL;
|
||||||
found:
|
found:
|
||||||
spin_unlock_irq(&gb_connections_lock);
|
spin_unlock_irq(&gb_connections_lock);
|
||||||
|
@ -204,7 +168,7 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irq(&gb_connections_lock);
|
spin_lock_irq(&gb_connections_lock);
|
||||||
_gb_hd_connection_insert(hd, connection);
|
list_add_tail(&connection->hd_links, &hd->connections);
|
||||||
list_add_tail(&connection->interface_links, &interface->connections);
|
list_add_tail(&connection->interface_links, &interface->connections);
|
||||||
spin_unlock_irq(&gb_connections_lock);
|
spin_unlock_irq(&gb_connections_lock);
|
||||||
|
|
||||||
|
@ -233,7 +197,7 @@ void gb_connection_destroy(struct gb_connection *connection)
|
||||||
}
|
}
|
||||||
spin_lock_irq(&gb_connections_lock);
|
spin_lock_irq(&gb_connections_lock);
|
||||||
list_del(&connection->interface_links);
|
list_del(&connection->interface_links);
|
||||||
_gb_hd_connection_remove(connection);
|
list_del(&connection->hd_links);
|
||||||
spin_unlock_irq(&gb_connections_lock);
|
spin_unlock_irq(&gb_connections_lock);
|
||||||
|
|
||||||
gb_connection_hd_cport_id_free(connection);
|
gb_connection_hd_cport_id_free(connection);
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct gb_connection {
|
||||||
u16 hd_cport_id;
|
u16 hd_cport_id;
|
||||||
u16 interface_cport_id;
|
u16 interface_cport_id;
|
||||||
|
|
||||||
struct rb_node hd_node;
|
struct list_head hd_links;
|
||||||
struct list_head interface_links;
|
struct list_head interface_links;
|
||||||
|
|
||||||
struct gb_protocol *protocol;
|
struct gb_protocol *protocol;
|
||||||
|
|
|
@ -186,7 +186,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver
|
||||||
hd->parent = parent;
|
hd->parent = parent;
|
||||||
hd->driver = driver;
|
hd->driver = driver;
|
||||||
INIT_LIST_HEAD(&hd->modules);
|
INIT_LIST_HEAD(&hd->modules);
|
||||||
hd->connections = RB_ROOT;
|
INIT_LIST_HEAD(&hd->connections);
|
||||||
ida_init(&hd->cport_id_map);
|
ida_init(&hd->cport_id_map);
|
||||||
spin_lock_init(&hd->cport_id_map_lock);
|
spin_lock_init(&hd->cport_id_map_lock);
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ struct greybus_host_device {
|
||||||
const struct greybus_host_driver *driver;
|
const struct greybus_host_driver *driver;
|
||||||
|
|
||||||
struct list_head modules;
|
struct list_head modules;
|
||||||
struct rb_root connections;
|
struct list_head connections;
|
||||||
struct ida cport_id_map;
|
struct ida cport_id_map;
|
||||||
spinlock_t cport_id_map_lock;
|
spinlock_t cport_id_map_lock;
|
||||||
u8 device_id;
|
u8 device_id;
|
||||||
|
|
Loading…
Reference in New Issue