1
2
3
4
5
6
7
8#ifndef _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
9#define _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
10
11#include <linux/atomic.h>
12#include <linux/kfifo.h>
13#include <linux/ktime.h>
14#include <linux/list.h>
15#include <linux/serdev.h>
16#include <linux/spinlock.h>
17#include <linux/types.h>
18#include <linux/wait.h>
19#include <linux/workqueue.h>
20
21#include <linux/surface_aggregator/serial_hub.h>
22#include "ssh_parser.h"
23
24
25
26
27
28
29
30
31enum ssh_ptl_state_flags {
32 SSH_PTL_SF_SHUTDOWN_BIT,
33};
34
35
36
37
38
39
40
41struct ssh_ptl_ops {
42 void (*data_received)(struct ssh_ptl *p, const struct ssam_span *data);
43};
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77struct ssh_ptl {
78 struct serdev_device *serdev;
79 unsigned long state;
80
81 struct {
82 spinlock_t lock;
83 struct list_head head;
84 } queue;
85
86 struct {
87 spinlock_t lock;
88 struct list_head head;
89 atomic_t count;
90 } pending;
91
92 struct {
93 atomic_t running;
94 struct task_struct *thread;
95 struct completion thread_cplt_tx;
96 struct completion thread_cplt_pkt;
97 struct wait_queue_head packet_wq;
98 } tx;
99
100 struct {
101 struct task_struct *thread;
102 struct wait_queue_head wq;
103 struct kfifo fifo;
104 struct sshp_buf buf;
105
106 struct {
107 u16 seqs[8];
108 u16 offset;
109 } blocked;
110 } rx;
111
112 struct {
113 spinlock_t lock;
114 ktime_t timeout;
115 ktime_t expires;
116 struct delayed_work reaper;
117 } rtx_timeout;
118
119 struct ssh_ptl_ops ops;
120};
121
122#define __ssam_prcond(func, p, fmt, ...) \
123 do { \
124 typeof(p) __p = (p); \
125 \
126 if (__p) \
127 func(__p, fmt, ##__VA_ARGS__); \
128 } while (0)
129
130#define ptl_dbg(p, fmt, ...) dev_dbg(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
131#define ptl_info(p, fmt, ...) dev_info(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
132#define ptl_warn(p, fmt, ...) dev_warn(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
133#define ptl_err(p, fmt, ...) dev_err(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
134#define ptl_dbg_cond(p, fmt, ...) __ssam_prcond(ptl_dbg, p, fmt, ##__VA_ARGS__)
135
136#define to_ssh_ptl(ptr, member) \
137 container_of(ptr, struct ssh_ptl, member)
138
139int ssh_ptl_init(struct ssh_ptl *ptl, struct serdev_device *serdev,
140 struct ssh_ptl_ops *ops);
141
142void ssh_ptl_destroy(struct ssh_ptl *ptl);
143
144
145
146
147
148
149
150
151static inline struct device *ssh_ptl_get_device(struct ssh_ptl *ptl)
152{
153 return ptl->serdev ? &ptl->serdev->dev : NULL;
154}
155
156int ssh_ptl_tx_start(struct ssh_ptl *ptl);
157int ssh_ptl_tx_stop(struct ssh_ptl *ptl);
158int ssh_ptl_rx_start(struct ssh_ptl *ptl);
159int ssh_ptl_rx_stop(struct ssh_ptl *ptl);
160void ssh_ptl_shutdown(struct ssh_ptl *ptl);
161
162int ssh_ptl_submit(struct ssh_ptl *ptl, struct ssh_packet *p);
163void ssh_ptl_cancel(struct ssh_packet *p);
164
165int ssh_ptl_rx_rcvbuf(struct ssh_ptl *ptl, const u8 *buf, size_t n);
166
167
168
169
170
171
172
173
174
175
176static inline void ssh_ptl_tx_wakeup_transfer(struct ssh_ptl *ptl)
177{
178 if (test_bit(SSH_PTL_SF_SHUTDOWN_BIT, &ptl->state))
179 return;
180
181 complete(&ptl->tx.thread_cplt_tx);
182}
183
184void ssh_packet_init(struct ssh_packet *packet, unsigned long type,
185 u8 priority, const struct ssh_packet_ops *ops);
186
187int ssh_ctrl_packet_cache_init(void);
188void ssh_ctrl_packet_cache_destroy(void);
189
190#endif
191