greybus: connection: add support for high-priority connections
[cascardo/linux.git] / drivers / staging / greybus / connection.h
index 6b40c4a..4d9f4c6 100644 (file)
 #define __CONNECTION_H
 
 #include <linux/list.h>
+#include <linux/kfifo.h>
+
+#define GB_CONNECTION_FLAG_CSD         BIT(0)
+#define GB_CONNECTION_FLAG_NO_FLOWCTRL BIT(1)
+#define GB_CONNECTION_FLAG_OFFLOADED   BIT(2)
+#define GB_CONNECTION_FLAG_CDSI1       BIT(3)
+#define GB_CONNECTION_FLAG_CONTROL     BIT(4)
+#define GB_CONNECTION_FLAG_HIGH_PRIO   BIT(5)
+
+#define GB_CONNECTION_FLAG_CORE_MASK   GB_CONNECTION_FLAG_CONTROL
 
 enum gb_connection_state {
-       GB_CONNECTION_STATE_INVALID     = 0,
-       GB_CONNECTION_STATE_DISABLED    = 1,
-       GB_CONNECTION_STATE_ENABLED     = 2,
-       GB_CONNECTION_STATE_ERROR       = 3,
-       GB_CONNECTION_STATE_DESTROYING  = 4,
+       GB_CONNECTION_STATE_DISABLED            = 0,
+       GB_CONNECTION_STATE_ENABLED_TX          = 1,
+       GB_CONNECTION_STATE_ENABLED             = 2,
+       GB_CONNECTION_STATE_DISCONNECTING       = 3,
 };
 
+struct gb_operation;
+
+typedef int (*gb_request_handler_t)(struct gb_operation *);
+
 struct gb_connection {
-       struct greybus_host_device      *hd;
+       struct gb_host_device           *hd;
+       struct gb_interface             *intf;
        struct gb_bundle                *bundle;
-       struct device                   dev;
+       struct kref                     kref;
        u16                             hd_cport_id;
        u16                             intf_cport_id;
 
        struct list_head                hd_links;
        struct list_head                bundle_links;
 
-       struct gb_protocol              *protocol;
-       u8                              protocol_id;
-       u8                              major;
-       u8                              minor;
+       gb_request_handler_t            handler;
+       unsigned long                   flags;
 
+       struct mutex                    mutex;
        spinlock_t                      lock;
        enum gb_connection_state        state;
        struct list_head                operations;
 
+       char                            name[16];
        struct workqueue_struct         *wq;
 
        atomic_t                        op_cycle;
 
        void                            *private;
+
+       bool                            mode_switch;
 };
-#define to_gb_connection(d) container_of(d, struct gb_connection, dev)
 
+struct gb_connection *gb_connection_create_static(struct gb_host_device *hd,
+                               u16 hd_cport_id, gb_request_handler_t handler);
+struct gb_connection *gb_connection_create_control(struct gb_interface *intf);
 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
-                               u16 cport_id, u8 protocol_id);
-struct gb_connection *gb_connection_create_range(struct greybus_host_device *hd,
-                          struct gb_bundle *bundle, struct device *parent,
-                          u16 cport_id, u8 protocol_id, u32 ida_start,
-                          u32 ida_end);
+                               u16 cport_id, gb_request_handler_t handler);
+struct gb_connection *gb_connection_create_flags(struct gb_bundle *bundle,
+                               u16 cport_id, gb_request_handler_t handler,
+                               unsigned long flags);
+struct gb_connection *gb_connection_create_offloaded(struct gb_bundle *bundle,
+                               u16 cport_id, unsigned long flags);
 void gb_connection_destroy(struct gb_connection *connection);
 
-int gb_connection_init(struct gb_connection *connection);
-void gb_connection_exit(struct gb_connection *connection);
-void gb_hd_connections_exit(struct greybus_host_device *hd);
+static inline bool gb_connection_is_static(struct gb_connection *connection)
+{
+       return !connection->intf;
+}
+
+int gb_connection_enable(struct gb_connection *connection);
+int gb_connection_enable_tx(struct gb_connection *connection);
+void gb_connection_disable_rx(struct gb_connection *connection);
+void gb_connection_disable(struct gb_connection *connection);
+void gb_connection_disable_forced(struct gb_connection *connection);
+
+void gb_connection_mode_switch_prepare(struct gb_connection *connection);
+void gb_connection_mode_switch_complete(struct gb_connection *connection);
 
-void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
+void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
                        u8 *data, size_t length);
 
-void gb_connection_bind_protocol(struct gb_connection *connection);
+void gb_connection_latency_tag_enable(struct gb_connection *connection);
+void gb_connection_latency_tag_disable(struct gb_connection *connection);
+
+static inline bool gb_connection_e2efc_enabled(struct gb_connection *connection)
+{
+       return !(connection->flags & GB_CONNECTION_FLAG_CSD);
+}
+
+static inline bool
+gb_connection_flow_control_disabled(struct gb_connection *connection)
+{
+       return connection->flags & GB_CONNECTION_FLAG_NO_FLOWCTRL;
+}
+
+static inline bool gb_connection_is_offloaded(struct gb_connection *connection)
+{
+       return connection->flags & GB_CONNECTION_FLAG_OFFLOADED;
+}
+
+static inline bool gb_connection_is_control(struct gb_connection *connection)
+{
+       return connection->flags & GB_CONNECTION_FLAG_CONTROL;
+}
+
+static inline void *gb_connection_get_data(struct gb_connection *connection)
+{
+       return connection->private;
+}
+
+static inline void gb_connection_set_data(struct gb_connection *connection,
+                                         void *data)
+{
+       connection->private = data;
+}
 
 #endif /* __CONNECTION_H */