#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. */
}
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)
{
struct gb_connection *connection = to_gb_connection(dev);
destroy_workqueue(connection->wq);
+ kfifo_free(&connection->ts_kfifo);
kfree(connection);
}
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;
pr_err("failed to add connection device for cport 0x%04hx\n",
cport_id);
- goto err_free_connection;
+ goto err_free_kfifo;
}
spin_lock_irq(&gb_connections_lock);
return connection;
+err_free_kfifo:
+ kfifo_free(&connection->ts_kfifo);
err_free_connection:
kfree(connection);
err_remove_ida:
#define __CONNECTION_H
#include <linux/list.h>
+#include <linux/kfifo.h>
enum gb_connection_state {
GB_CONNECTION_STATE_INVALID = 0,
struct list_head operations;
struct workqueue_struct *wq;
+ struct kfifo ts_kfifo;
atomic_t op_cycle;
void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
u8 *data, size_t length);
+void gb_connection_push_timestamp(struct gb_connection *connection);
+int gb_connection_pop_timestamp(struct gb_connection *connection,
+ struct timeval *tv);
void gb_connection_bind_protocol(struct gb_connection *connection);