xref: /openbmc/linux/drivers/platform/surface/aggregator/ssh_request_layer.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1  /* SPDX-License-Identifier: GPL-2.0+ */
2  /*
3   * SSH request transport layer.
4   *
5   * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com>
6   */
7  
8  #ifndef _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
9  #define _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
10  
11  #include <linux/atomic.h>
12  #include <linux/ktime.h>
13  #include <linux/list.h>
14  #include <linux/spinlock.h>
15  #include <linux/workqueue.h>
16  
17  #include <linux/surface_aggregator/serial_hub.h>
18  #include <linux/surface_aggregator/controller.h>
19  
20  #include "ssh_packet_layer.h"
21  
22  /**
23   * enum ssh_rtl_state_flags - State-flags for &struct ssh_rtl.
24   *
25   * @SSH_RTL_SF_SHUTDOWN_BIT:
26   *	Indicates that the request transport layer has been shut down or is
27   *	being shut down and should not accept any new requests.
28   */
29  enum ssh_rtl_state_flags {
30  	SSH_RTL_SF_SHUTDOWN_BIT,
31  };
32  
33  /**
34   * struct ssh_rtl_ops - Callback operations for request transport layer.
35   * @handle_event: Function called when a SSH event has been received. The
36   *                specified function takes the request layer, received command
37   *                struct, and corresponding payload as arguments. If the event
38   *                has no payload, the payload span is empty (not %NULL).
39   */
40  struct ssh_rtl_ops {
41  	void (*handle_event)(struct ssh_rtl *rtl, const struct ssh_command *cmd,
42  			     const struct ssam_span *data);
43  };
44  
45  /**
46   * struct ssh_rtl - SSH request transport layer.
47   * @ptl:           Underlying packet transport layer.
48   * @state:         State(-flags) of the transport layer.
49   * @queue:         Request submission queue.
50   * @queue.lock:    Lock for modifying the request submission queue.
51   * @queue.head:    List-head of the request submission queue.
52   * @pending:       Set/list of pending requests.
53   * @pending.lock:  Lock for modifying the request set.
54   * @pending.head:  List-head of the pending set/list.
55   * @pending.count: Number of currently pending requests.
56   * @tx:            Transmitter subsystem.
57   * @tx.work:       Transmitter work item.
58   * @rtx_timeout:   Retransmission timeout subsystem.
59   * @rtx_timeout.lock:    Lock for modifying the retransmission timeout reaper.
60   * @rtx_timeout.timeout: Timeout interval for retransmission.
61   * @rtx_timeout.expires: Time specifying when the reaper work is next scheduled.
62   * @rtx_timeout.reaper:  Work performing timeout checks and subsequent actions.
63   * @ops:           Request layer operations.
64   */
65  struct ssh_rtl {
66  	struct ssh_ptl ptl;
67  	unsigned long state;
68  
69  	struct {
70  		spinlock_t lock;
71  		struct list_head head;
72  	} queue;
73  
74  	struct {
75  		spinlock_t lock;
76  		struct list_head head;
77  		atomic_t count;
78  	} pending;
79  
80  	struct {
81  		struct work_struct work;
82  	} tx;
83  
84  	struct {
85  		spinlock_t lock;
86  		ktime_t timeout;
87  		ktime_t expires;
88  		struct delayed_work reaper;
89  	} rtx_timeout;
90  
91  	struct ssh_rtl_ops ops;
92  };
93  
94  #define rtl_dbg(r, fmt, ...)  ptl_dbg(&(r)->ptl, fmt, ##__VA_ARGS__)
95  #define rtl_info(p, fmt, ...) ptl_info(&(p)->ptl, fmt, ##__VA_ARGS__)
96  #define rtl_warn(r, fmt, ...) ptl_warn(&(r)->ptl, fmt, ##__VA_ARGS__)
97  #define rtl_err(r, fmt, ...)  ptl_err(&(r)->ptl, fmt, ##__VA_ARGS__)
98  #define rtl_dbg_cond(r, fmt, ...) __ssam_prcond(rtl_dbg, r, fmt, ##__VA_ARGS__)
99  
100  #define to_ssh_rtl(ptr, member) \
101  	container_of(ptr, struct ssh_rtl, member)
102  
103  /**
104   * ssh_rtl_get_device() - Get device associated with request transport layer.
105   * @rtl: The request transport layer.
106   *
107   * Return: Returns the device on which the given request transport layer
108   * builds upon.
109   */
ssh_rtl_get_device(struct ssh_rtl * rtl)110  static inline struct device *ssh_rtl_get_device(struct ssh_rtl *rtl)
111  {
112  	return ssh_ptl_get_device(&rtl->ptl);
113  }
114  
115  /**
116   * ssh_request_rtl() - Get request transport layer associated with request.
117   * @rqst: The request to get the request transport layer reference for.
118   *
119   * Return: Returns the &struct ssh_rtl associated with the given SSH request.
120   */
ssh_request_rtl(struct ssh_request * rqst)121  static inline struct ssh_rtl *ssh_request_rtl(struct ssh_request *rqst)
122  {
123  	struct ssh_ptl *ptl;
124  
125  	ptl = READ_ONCE(rqst->packet.ptl);
126  	return likely(ptl) ? to_ssh_rtl(ptl, ptl) : NULL;
127  }
128  
129  int ssh_rtl_submit(struct ssh_rtl *rtl, struct ssh_request *rqst);
130  bool ssh_rtl_cancel(struct ssh_request *rqst, bool pending);
131  
132  int ssh_rtl_init(struct ssh_rtl *rtl, struct serdev_device *serdev,
133  		 const struct ssh_rtl_ops *ops);
134  
135  int ssh_rtl_start(struct ssh_rtl *rtl);
136  int ssh_rtl_flush(struct ssh_rtl *rtl, unsigned long timeout);
137  void ssh_rtl_shutdown(struct ssh_rtl *rtl);
138  void ssh_rtl_destroy(struct ssh_rtl *rtl);
139  
140  int ssh_request_init(struct ssh_request *rqst, enum ssam_request_flags flags,
141  		     const struct ssh_request_ops *ops);
142  
143  #endif /* _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H */
144