summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/connection.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman2014-10-24 11:34:46 +0200
committerGreg Kroah-Hartman2014-10-24 11:40:59 +0200
commitf0f61b90427b776b884821cde483528580f6d630 (patch)
tree51666ef5ef41806e6d8f5f5b27ce69da286a460e /drivers/staging/greybus/connection.c
parentgreybus: update AP id service message (diff)
downloadkernel-qcow2-linux-f0f61b90427b776b884821cde483528580f6d630.tar.gz
kernel-qcow2-linux-f0f61b90427b776b884821cde483528580f6d630.tar.xz
kernel-qcow2-linux-f0f61b90427b776b884821cde483528580f6d630.zip
greybus: hook up greybus to the driver model
This patch hooks up modules, interfaces, and connections to the driver model. Now we have a correct hierarchy, and drivers can be correctly bound to the proper portions in the future. Devices are correctly reference counted and torn down in the proper order on removal of a module. Some basic sysfs attributes have been created for interfaces and connections. Module attributes are not working properly, but that will be fixed in future changes. This has been tested on Alex's machine, with multiple hotplug and unplug operations of a module working correctly. Signed-off-by: Greg Kroah-Hartman <greg@kroah.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/greybus/connection.c')
-rw-r--r--drivers/staging/greybus/connection.c59
1 files changed, 56 insertions, 3 deletions
diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
index b1e933fc7044..2d71679ff66c 100644
--- a/drivers/staging/greybus/connection.c
+++ b/drivers/staging/greybus/connection.c
@@ -111,6 +111,44 @@ static void connection_timeout(struct work_struct *work)
printk("timeout!\n");
}
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct gb_connection *connection = to_gb_connection(dev);
+
+ return sprintf(buf, "%d", connection->state);
+}
+static DEVICE_ATTR_RO(state);
+
+static ssize_t protocol_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct gb_connection *connection = to_gb_connection(dev);
+
+ return sprintf(buf, "%d", connection->protocol);
+}
+static DEVICE_ATTR_RO(protocol);
+
+static struct attribute *connection_attrs[] = {
+ &dev_attr_state.attr,
+ &dev_attr_protocol.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(connection);
+
+static void gb_connection_release(struct device *dev)
+{
+ struct gb_connection *connection = to_gb_connection(dev);
+
+ kfree(connection);
+}
+
+static struct device_type greybus_connection_type = {
+ .name = "greybus_connection",
+ .release = gb_connection_release,
+};
+
/*
* Set up a Greybus connection, representing the bidirectional link
* between a CPort on a (local) Greybus host device and a CPort on
@@ -127,6 +165,7 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
{
struct gb_connection *connection;
struct greybus_host_device *hd;
+ int retval;
connection = kzalloc(sizeof(*connection), GFP_KERNEL);
if (!connection)
@@ -145,6 +184,21 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
connection->protocol = protocol;
connection->state = GB_CONNECTION_STATE_DISABLED;
+ connection->dev.parent = &interface->dev;
+ connection->dev.driver = NULL;
+ connection->dev.bus = &greybus_bus_type;
+ connection->dev.type = &greybus_connection_type;
+ connection->dev.groups = connection_groups;
+ device_initialize(&connection->dev);
+ dev_set_name(&connection->dev, "%s:%d",
+ dev_name(&interface->dev), cport_id);
+
+ retval = device_add(&connection->dev);
+ if (retval) {
+ kfree(connection);
+ return NULL;
+ }
+
spin_lock_irq(&gb_connections_lock);
_gb_hd_connection_insert(hd, connection);
list_add_tail(&connection->interface_links, &interface->connections);
@@ -182,9 +236,8 @@ void gb_connection_destroy(struct gb_connection *connection)
spin_unlock_irq(&gb_connections_lock);
gb_connection_hd_cport_id_free(connection);
- /* kref_put(connection->interface); */
- /* kref_put(connection->hd); */
- kfree(connection);
+
+ device_del(&connection->dev);
}
u16 gb_connection_operation_id(struct gb_connection *connection)