summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/connection.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2015-08-11 22:14:06 -0700
committerGreg Kroah-Hartman <gregkh@google.com>2015-08-11 22:14:06 -0700
commitd706ef8f1b2add4abbbeacbbaaf0c304b25f4476 (patch)
treebafc7e345469b4209ccaa0cd6c73a1d4dc04a8a0 /drivers/staging/greybus/connection.c
parent542f27a18f574d3807735bdcdbde8f8423c2f817 (diff)
parent58dab0f2a872be5dc2bdb15f3dc487b4a1b41aaf (diff)
downloadlinux-stable-d706ef8f1b2add4abbbeacbbaaf0c304b25f4476.tar.gz
linux-stable-d706ef8f1b2add4abbbeacbbaaf0c304b25f4476.tar.bz2
linux-stable-d706ef8f1b2add4abbbeacbbaaf0c304b25f4476.zip
greybus: Merge branch 'master' into branch 'svc'.
This drags in the firmware driver, and the start of some loopback changes. Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/connection.c')
-rw-r--r--drivers/staging/greybus/connection.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
index ef837c50fcfb..eae6ad143d0b 100644
--- a/drivers/staging/greybus/connection.c
+++ b/drivers/staging/greybus/connection.c
@@ -11,6 +11,10 @@
#include "greybus.h"
+#define GB_CONNECTION_TS_KFIFO_ELEMENTS 2
+#define GB_CONNECTION_TS_KFIFO_LEN \
+ (GB_CONNECTION_TS_KFIFO_ELEMENTS * sizeof(struct timeval))
+
static DEFINE_SPINLOCK(gb_connections_lock);
/* This is only used at initialization time; no locking is required. */
@@ -63,6 +67,29 @@ void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
}
EXPORT_SYMBOL_GPL(greybus_data_rcvd);
+void gb_connection_push_timestamp(struct gb_connection *connection)
+{
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+ kfifo_in_locked(&connection->ts_kfifo, (void *)&tv,
+ sizeof(struct timeval), &connection->lock);
+}
+EXPORT_SYMBOL_GPL(gb_connection_push_timestamp);
+
+int gb_connection_pop_timestamp(struct gb_connection *connection,
+ struct timeval *tv)
+{
+ int retval;
+
+ if (!kfifo_len(&connection->ts_kfifo))
+ return -ENOMEM;
+ retval = kfifo_out_locked(&connection->ts_kfifo, (void *)tv,
+ sizeof(*tv), &connection->lock);
+ return retval;
+}
+EXPORT_SYMBOL_GPL(gb_connection_pop_timestamp);
+
static ssize_t state_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -102,6 +129,7 @@ static void gb_connection_release(struct device *dev)
struct gb_connection *connection = to_gb_connection(dev);
destroy_workqueue(connection->wq);
+ kfifo_free(&connection->ts_kfifo);
kfree(connection);
}
@@ -222,6 +250,10 @@ gb_connection_create_range(struct greybus_host_device *hd,
if (!connection->wq)
goto err_free_connection;
+ if (kfifo_alloc(&connection->ts_kfifo, GB_CONNECTION_TS_KFIFO_LEN,
+ GFP_KERNEL))
+ goto err_free_connection;
+
connection->dev.parent = parent;
connection->dev.bus = &greybus_bus_type;
connection->dev.type = &greybus_connection_type;
@@ -238,7 +270,7 @@ gb_connection_create_range(struct greybus_host_device *hd,
pr_err("failed to add connection device for cport 0x%04hx\n",
cport_id);
- goto err_remove_ida;
+ goto err_free_kfifo;
}
spin_lock_irq(&gb_connections_lock);
@@ -264,6 +296,8 @@ gb_connection_create_range(struct greybus_host_device *hd,
return connection;
+err_free_kfifo:
+ kfifo_free(&connection->ts_kfifo);
err_free_connection:
kfree(connection);
err_remove_ida:
@@ -394,7 +428,19 @@ int gb_connection_init(struct gb_connection *connection)
* this for SVC as that is initiated by the SVC.
*/
if (connection->hd_cport_id != GB_SVC_CPORT_ID) {
- ret = gb_protocol_get_version(connection, NULL, 0);
+ bool send_request = false;
+
+ /*
+ * We need to send the protocol version of the firmware protocol
+ * supported by AP and so this special case.
+ */
+ if (connection->protocol->id == GREYBUS_PROTOCOL_FIRMWARE)
+ send_request = true;
+
+ // FIXME: Should we always send the protocol version AP can
+ // support ?
+
+ ret = gb_protocol_get_version(connection, send_request);
if (ret) {
dev_err(&connection->dev,
"Failed to get version CPort-%d (%d)\n",