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:
Alex Elder 2014-10-03 14:14:22 -05:00 committed by Greg Kroah-Hartman
parent d7f9be4867
commit 748e1230cb
5 changed files with 17 additions and 5 deletions

View File

@ -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); */

View File

@ -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) {

View File

@ -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 */

View File

@ -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);

View File

@ -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 */
};