0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _SURFACE_AGGREGATOR_CONTROLLER_H
0009 #define _SURFACE_AGGREGATOR_CONTROLLER_H
0010
0011 #include <linux/kref.h>
0012 #include <linux/list.h>
0013 #include <linux/mutex.h>
0014 #include <linux/rbtree.h>
0015 #include <linux/rwsem.h>
0016 #include <linux/serdev.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/srcu.h>
0019 #include <linux/types.h>
0020 #include <linux/workqueue.h>
0021
0022 #include <linux/surface_aggregator/controller.h>
0023 #include <linux/surface_aggregator/serial_hub.h>
0024
0025 #include "ssh_request_layer.h"
0026
0027
0028
0029
0030
0031
0032
0033
0034 struct ssh_seq_counter {
0035 u8 value;
0036 };
0037
0038
0039
0040
0041
0042 struct ssh_rqid_counter {
0043 u16 value;
0044 };
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 struct ssam_nf_head {
0055 struct srcu_struct srcu;
0056 struct list_head head;
0057 };
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 struct ssam_nf {
0069 struct mutex lock;
0070 struct rb_root refcount;
0071 struct ssam_nf_head head[SSH_NUM_EVENTS];
0072 };
0073
0074
0075
0076
0077 struct ssam_cplt;
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 struct ssam_event_item {
0088 struct list_head node;
0089 u16 rqid;
0090
0091 struct {
0092 void (*free)(struct ssam_event_item *event);
0093 } ops;
0094
0095 struct ssam_event event;
0096 };
0097
0098
0099
0100
0101
0102
0103
0104
0105 struct ssam_event_queue {
0106 struct ssam_cplt *cplt;
0107
0108 spinlock_t lock;
0109 struct list_head head;
0110 struct work_struct work;
0111 };
0112
0113
0114
0115
0116
0117 struct ssam_event_target {
0118 struct ssam_event_queue queue[SSH_NUM_EVENTS];
0119 };
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 struct ssam_cplt {
0132 struct device *dev;
0133 struct workqueue_struct *wq;
0134
0135 struct {
0136 struct ssam_event_target target[SSH_NUM_TARGETS];
0137 struct ssam_nf notif;
0138 } event;
0139 };
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 enum ssam_controller_state {
0158 SSAM_CONTROLLER_UNINITIALIZED,
0159 SSAM_CONTROLLER_INITIALIZED,
0160 SSAM_CONTROLLER_STARTED,
0161 SSAM_CONTROLLER_STOPPED,
0162 SSAM_CONTROLLER_SUSPENDED,
0163 };
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 struct ssam_controller_caps {
0176 u32 ssh_power_profile;
0177 u32 ssh_buffer_size;
0178 u32 screen_on_sleep_idle_timeout;
0179 u32 screen_off_sleep_idle_timeout;
0180 u32 d3_closes_handle:1;
0181 };
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 struct ssam_controller {
0199 struct kref kref;
0200
0201 struct rw_semaphore lock;
0202 enum ssam_controller_state state;
0203
0204 struct ssh_rtl rtl;
0205 struct ssam_cplt cplt;
0206
0207 struct {
0208 struct ssh_seq_counter seq;
0209 struct ssh_rqid_counter rqid;
0210 } counter;
0211
0212 struct {
0213 int num;
0214 bool wakeup_enabled;
0215 } irq;
0216
0217 struct ssam_controller_caps caps;
0218 };
0219
0220 #define to_ssam_controller(ptr, member) \
0221 container_of(ptr, struct ssam_controller, member)
0222
0223 #define ssam_dbg(ctrl, fmt, ...) rtl_dbg(&(ctrl)->rtl, fmt, ##__VA_ARGS__)
0224 #define ssam_info(ctrl, fmt, ...) rtl_info(&(ctrl)->rtl, fmt, ##__VA_ARGS__)
0225 #define ssam_warn(ctrl, fmt, ...) rtl_warn(&(ctrl)->rtl, fmt, ##__VA_ARGS__)
0226 #define ssam_err(ctrl, fmt, ...) rtl_err(&(ctrl)->rtl, fmt, ##__VA_ARGS__)
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 static inline
0241 int ssam_controller_receive_buf(struct ssam_controller *ctrl,
0242 const unsigned char *buf, size_t n)
0243 {
0244 return ssh_ptl_rx_rcvbuf(&ctrl->rtl.ptl, buf, n);
0245 }
0246
0247
0248
0249
0250
0251
0252 static inline void ssam_controller_write_wakeup(struct ssam_controller *ctrl)
0253 {
0254 ssh_ptl_tx_wakeup_transfer(&ctrl->rtl.ptl);
0255 }
0256
0257 int ssam_controller_init(struct ssam_controller *ctrl, struct serdev_device *s);
0258 int ssam_controller_start(struct ssam_controller *ctrl);
0259 void ssam_controller_shutdown(struct ssam_controller *ctrl);
0260 void ssam_controller_destroy(struct ssam_controller *ctrl);
0261
0262 int ssam_notifier_disable_registered(struct ssam_controller *ctrl);
0263 void ssam_notifier_restore_registered(struct ssam_controller *ctrl);
0264
0265 int ssam_irq_setup(struct ssam_controller *ctrl);
0266 void ssam_irq_free(struct ssam_controller *ctrl);
0267 int ssam_irq_arm_for_wakeup(struct ssam_controller *ctrl);
0268 void ssam_irq_disarm_wakeup(struct ssam_controller *ctrl);
0269
0270 void ssam_controller_lock(struct ssam_controller *c);
0271 void ssam_controller_unlock(struct ssam_controller *c);
0272
0273 int ssam_get_firmware_version(struct ssam_controller *ctrl, u32 *version);
0274 int ssam_ctrl_notif_display_off(struct ssam_controller *ctrl);
0275 int ssam_ctrl_notif_display_on(struct ssam_controller *ctrl);
0276 int ssam_ctrl_notif_d0_exit(struct ssam_controller *ctrl);
0277 int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl);
0278
0279 int ssam_controller_suspend(struct ssam_controller *ctrl);
0280 int ssam_controller_resume(struct ssam_controller *ctrl);
0281
0282 int ssam_event_item_cache_init(void);
0283 void ssam_event_item_cache_destroy(void);
0284
0285 #endif