mirror of https://gitee.com/openkylin/linux.git
greybus: fix some hasty bugs
Fix some omissions found in the code. - initialize and use the host device connections list - rename the interface connections list (was "functions") - use the interface connections list - define a spinlock protecting the connections lists - declare gb_operation_submit() in "operation.h" And the cport id map lock is per-host device, it's shared across all host devices. There's no need for one in struct greybus_host_device. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
parent
d7f9be4867
commit
748e1230cb
|
@ -11,6 +11,8 @@
|
|||
#include "kernel_ver.h"
|
||||
#include "greybus.h"
|
||||
|
||||
static DEFINE_SPINLOCK(gb_connections_lock);
|
||||
|
||||
/*
|
||||
* Set up a Greybus connection, representing the bidirectional link
|
||||
* between a CPort on a (local) Greybus host device and a CPort on
|
||||
|
@ -43,6 +45,11 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
|
|||
connection->interface_cport_id = cport_id;
|
||||
connection->protocol = protocol;
|
||||
|
||||
spin_lock_irq(&gb_connections_lock);
|
||||
list_add_tail(&connection->hd_links, &hd->connections);
|
||||
list_add_tail(&connection->interface_links, &interface->connections);
|
||||
spin_unlock_irq(&gb_connections_lock);
|
||||
|
||||
INIT_LIST_HEAD(&connection->operations);
|
||||
atomic_set(&connection->op_cycle, 0);
|
||||
|
||||
|
@ -60,6 +67,11 @@ void gb_connection_destroy(struct gb_connection *connection)
|
|||
/* XXX Need to wait for any outstanding requests to complete */
|
||||
WARN_ON(!list_empty(&connection->operations));
|
||||
|
||||
spin_lock_irq(&gb_connections_lock);
|
||||
list_del(&connection->hd_links);
|
||||
list_del(&connection->interface_links);
|
||||
spin_unlock_irq(&gb_connections_lock);
|
||||
|
||||
greybus_hd_cport_id_free(connection->hd, connection->hd_cport_id);
|
||||
/* kref_put(connection->interface); */
|
||||
/* kref_put(connection->hd); */
|
||||
|
|
|
@ -298,9 +298,9 @@ u16 greybus_hd_cport_id_alloc(struct greybus_host_device *hd)
|
|||
return CPORT_ID_BAD;
|
||||
|
||||
spin_lock_irq(&cport_id_map_lock);
|
||||
cport_id = find_next_zero_bit(hd->cport_id_map, hd->cport_id_count,
|
||||
cport_id = find_next_zero_bit(hd->cport_id_map, HOST_DEV_CPORT_ID_MAX,
|
||||
hd->cport_id_next_free);
|
||||
if (cport_id < hd->cport_id_count) {
|
||||
if (cport_id < HOST_DEV_CPORT_ID_MAX) {
|
||||
hd->cport_id_next_free = cport_id + 1; /* Success */
|
||||
hd->cport_id_count++;
|
||||
} else {
|
||||
|
@ -367,6 +367,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver
|
|||
hd->parent = parent;
|
||||
hd->driver = driver;
|
||||
INIT_LIST_HEAD(&hd->modules);
|
||||
INIT_LIST_HEAD(&hd->connections);
|
||||
|
||||
/* Pre-allocate CPort 0 for control stuff. XXX */
|
||||
if (greybus_hd_cport_id_alloc(hd) != 0) {
|
||||
|
|
|
@ -194,7 +194,6 @@ struct greybus_host_device {
|
|||
struct list_head modules;
|
||||
struct list_head connections;
|
||||
|
||||
spinlock_t cport_id_map_lock;
|
||||
DECLARE_BITMAP(cport_id_map, HOST_DEV_CPORT_ID_MAX);
|
||||
u16 cport_id_count; /* How many have been allocated */
|
||||
u16 cport_id_next_free; /* Where to start checking anyway */
|
||||
|
|
|
@ -33,7 +33,7 @@ gb_interface_create(struct gb_module *gmod, u8 interface_id)
|
|||
|
||||
interface->gmod = gmod; /* XXX refcount? */
|
||||
interface->id = interface_id;
|
||||
INIT_LIST_HEAD(&interface->functions);
|
||||
INIT_LIST_HEAD(&interface->connections);
|
||||
|
||||
spin_lock_irq(&gb_interfaces_lock);
|
||||
list_add_tail(&interface->links, &gmod->interfaces);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
struct gb_interface {
|
||||
struct gb_module *gmod;
|
||||
u8 id;
|
||||
struct list_head functions;
|
||||
struct list_head connections;
|
||||
|
||||
struct list_head links; /* module->interfaces */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue