blob: c44aa93a04c713f28ee9b6892ecc844d1a575606 [file] [log] [blame]
Chris Lew4039ef92017-01-31 16:16:20 -08001/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
Chris Lewfa6135e2016-08-01 13:29:46 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/gfp.h>
16#include <linux/kernel.h>
17#include <linux/kthread.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/mutex.h>
21#include <linux/of.h>
22#include <linux/platform_device.h>
23#include <linux/printk.h>
24#include <linux/sched.h>
25#include <linux/seq_file.h>
26#include <linux/slab.h>
27#include <linux/spi/spi.h>
28#include <linux/spinlock.h>
29#include <linux/srcu.h>
30#include <linux/wait.h>
31#include <linux/component.h>
32#include <soc/qcom/tracer_pkt.h>
33#include <sound/wcd-dsp-mgr.h>
34#include <sound/wcd-spi.h>
35#include "glink_core_if.h"
36#include "glink_private.h"
37#include "glink_xprt_if.h"
38
39#define XPRT_NAME "spi"
40#define FIFO_ALIGNMENT 16
41#define FIFO_FULL_RESERVE 8
42#define TX_BLOCKED_CMD_RESERVE 16
43#define TRACER_PKT_FEATURE BIT(2)
44#define DEFAULT_FIFO_SIZE 1024
45#define SHORT_PKT_SIZE 16
46#define XPRT_ALIGNMENT 4
47
48#define MAX_INACTIVE_CYCLES 50
49#define POLL_INTERVAL_US 500
50
51#define ACTIVE_TX BIT(0)
52#define ACTIVE_RX BIT(1)
53
54#define ID_MASK 0xFFFFFF
55/**
56 * enum command_types - definition of the types of commands sent/received
57 * @VERSION_CMD: Version and feature set supported
58 * @VERSION_ACK_CMD: Response for @VERSION_CMD
59 * @OPEN_CMD: Open a channel
60 * @CLOSE_CMD: Close a channel
61 * @OPEN_ACK_CMD: Response to @OPEN_CMD
62 * @CLOSE_ACK_CMD: Response for @CLOSE_CMD
63 * @RX_INTENT_CMD: RX intent for a channel is queued
64 * @RX_DONE_CMD: Use of RX intent for a channel is complete
65 * @RX_DONE_W_REUSE_CMD: Same as @RX_DONE but also reuse the used intent
66 * @RX_INTENT_REQ_CMD: Request to have RX intent queued
67 * @RX_INTENT_REQ_ACK_CMD: Response for @RX_INTENT_REQ_CMD
68 * @TX_DATA_CMD: Start of a data transfer
69 * @TX_DATA_CONT_CMD: Continuation or end of a data transfer
70 * @READ_NOTIF_CMD: Request for a notification when this cmd is read
71 * @SIGNALS_CMD: Sideband signals
72 * @TRACER_PKT_CMD: Start of a Tracer Packet Command
73 * @TRACER_PKT_CONT_CMD: Continuation or end of a Tracer Packet Command
74 * @TX_SHORT_DATA_CMD: Transmit short packets
75 */
76enum command_types {
77 VERSION_CMD,
78 VERSION_ACK_CMD,
79 OPEN_CMD,
80 CLOSE_CMD,
81 OPEN_ACK_CMD,
82 CLOSE_ACK_CMD,
83 RX_INTENT_CMD,
84 RX_DONE_CMD,
85 RX_DONE_W_REUSE_CMD,
86 RX_INTENT_REQ_CMD,
87 RX_INTENT_REQ_ACK_CMD,
88 TX_DATA_CMD,
89 TX_DATA_CONT_CMD,
90 READ_NOTIF_CMD,
91 SIGNALS_CMD,
92 TRACER_PKT_CMD,
93 TRACER_PKT_CONT_CMD,
94 TX_SHORT_DATA_CMD,
95};
96
97/**
98 * struct glink_cmpnt - Component to cache WDSP component and its operations
99 * @master_dev: Device structure corresponding to WDSP device.
100 * @master_ops: Operations supported by the WDSP device.
101 */
102struct glink_cmpnt {
103 struct device *master_dev;
104 struct wdsp_mgr_ops *master_ops;
105};
106
107/**
108 * struct edge_info - local information for managing a single complete edge
109 * @xprt_if: The transport interface registered with the
110 * glink core associated with this edge.
111 * @xprt_cfg: The transport configuration for the glink core
112 * assocaited with this edge.
113 * @subsys_name: Name of the remote subsystem in the edge.
Chris Lewbb58f022017-06-27 16:54:11 -0700114 * @spi_ops: Function pointers for ops provided by spi.
Chris Lewfa6135e2016-08-01 13:29:46 -0700115 * @fifo_size: Size of the FIFO at the remote end.
116 * @tx_fifo_start: Base Address of the TX FIFO.
117 * @tx_fifo_end: End Address of the TX FIFO.
118 * @rx_fifo_start: Base Address of the RX FIFO.
119 * @rx_fifo_end: End Address of the RX FIFO.
120 * @tx_fifo_read_reg_addr: Address of the TX FIFO Read Index Register.
121 * @tx_fifo_write_reg_addr: Address of the TX FIFO Write Index Register.
122 * @rx_fifo_read_reg_addr: Address of the RX FIFO Read Index Register.
123 * @rx_fifo_write_reg_addr: Address of the RX FIFO Write Index Register.
124 * @kwork: Work to be executed when receiving data.
125 * @kworker: Handle to the entity processing @kwork.
126 * @task: Handle to the task context that runs @kworker.
127 * @use_ref: Active users of this transport grab a
128 * reference. Used for SSR synchronization.
129 * @in_ssr: Signals if this transport is in ssr.
130 * @write_lock: Lock to serialize write/tx operation.
131 * @tx_blocked_queue: Queue of entities waiting for the remote side to
132 * signal the resumption of TX.
133 * @tx_resume_needed: A tx resume signal needs to be sent to the glink
134 * core.
135 * @tx_blocked_signal_sent: Flag to indicate the flush signal has already
136 * been sent, and a response is pending from the
137 * remote side. Protected by @write_lock.
138 * @num_pw_states: Size of @ramp_time_us.
139 * @ramp_time_us: Array of ramp times in microseconds where array
140 * index position represents a power state.
141 * @activity_flag: Flag indicating active TX and RX.
142 * @activity_lock: Lock to synchronize access to activity flag.
143 * @cmpnt: Component to interface with the remote device.
144 */
145struct edge_info {
146 struct list_head list;
147 struct glink_transport_if xprt_if;
148 struct glink_core_transport_cfg xprt_cfg;
149 char subsys_name[GLINK_NAME_SIZE];
Chris Lewbb58f022017-06-27 16:54:11 -0700150 struct wcd_spi_ops spi_ops;
Chris Lewfa6135e2016-08-01 13:29:46 -0700151
152 uint32_t fifo_size;
153 uint32_t tx_fifo_start;
154 uint32_t tx_fifo_end;
155 uint32_t rx_fifo_start;
156 uint32_t rx_fifo_end;
157 unsigned int tx_fifo_read_reg_addr;
158 unsigned int tx_fifo_write_reg_addr;
159 unsigned int rx_fifo_read_reg_addr;
160 unsigned int rx_fifo_write_reg_addr;
161
162 struct kthread_work kwork;
163 struct kthread_worker kworker;
164 struct task_struct *task;
165 struct srcu_struct use_ref;
166 bool in_ssr;
167 struct mutex write_lock;
168 wait_queue_head_t tx_blocked_queue;
169 bool tx_resume_needed;
170 bool tx_blocked_signal_sent;
171
172 uint32_t num_pw_states;
173 unsigned long *ramp_time_us;
174
175 uint32_t activity_flag;
176 spinlock_t activity_lock;
177
178 struct glink_cmpnt cmpnt;
179};
180
181static uint32_t negotiate_features_v1(struct glink_transport_if *if_ptr,
182 const struct glink_core_version *version,
183 uint32_t features);
184static DEFINE_SPINLOCK(edge_infos_lock);
185static LIST_HEAD(edge_infos);
186static struct glink_core_version versions[] = {
187 {1, TRACER_PKT_FEATURE, negotiate_features_v1},
188};
189
190/**
191 * negotiate_features_v1() - determine what features of a version can be used
192 * @if_ptr: The transport for which features are negotiated for.
193 * @version: The version negotiated.
194 * @features: The set of requested features.
195 *
196 * Return: What set of the requested features can be supported.
197 */
198static uint32_t negotiate_features_v1(struct glink_transport_if *if_ptr,
199 const struct glink_core_version *version,
200 uint32_t features)
201{
202 return features & version->features;
203}
204
205/**
206 * wdsp_suspend() - Vote for the WDSP device suspend
207 * @cmpnt: Component to identify the WDSP device.
208 *
209 * Return: 0 on success, standard Linux error codes on failure.
210 */
211static int wdsp_suspend(struct glink_cmpnt *cmpnt)
212{
213 int rc = 0;
214
215 if (cmpnt && cmpnt->master_dev &&
216 cmpnt->master_ops && cmpnt->master_ops->suspend)
217 rc = cmpnt->master_ops->suspend(cmpnt->master_dev);
218 return rc;
219}
220
221/**
222 * wdsp_resume() - Vote for the WDSP device resume
223 * @cmpnt: Component to identify the WDSP device.
224 *
225 * Return: 0 on success, standard Linux error codes on failure.
226 */
227static int wdsp_resume(struct glink_cmpnt *cmpnt)
228{
229 int rc = 0;
230
231 if (cmpnt && cmpnt->master_dev &&
232 cmpnt->master_ops && cmpnt->master_ops->resume)
233 rc = cmpnt->master_ops->resume(cmpnt->master_dev);
234 return rc;
235}
236
237/**
238 * glink_spi_xprt_set_poll_mode() - Set the transport to polling mode
239 * @einfo: Edge information corresponding to the transport.
240 *
241 * This helper function indicates the start of RX polling. This will
242 * prevent the system from suspending and keeps polling for RX for a
243 * pre-defined duration.
244 */
245static void glink_spi_xprt_set_poll_mode(struct edge_info *einfo)
246{
247 unsigned long flags;
248
249 spin_lock_irqsave(&einfo->activity_lock, flags);
250 einfo->activity_flag |= ACTIVE_RX;
251 spin_unlock_irqrestore(&einfo->activity_lock, flags);
252 if (!strcmp(einfo->xprt_cfg.edge, "wdsp"))
253 wdsp_resume(&einfo->cmpnt);
254}
255
256/**
257 * glink_spi_xprt_set_irq_mode() - Set the transport to IRQ mode
258 * @einfo: Edge information corresponding to the transport.
259 *
260 * This helper indicates the end of RX polling. This will allow the
261 * system to suspend and new RX data can be handled only through an IRQ.
262 */
263static void glink_spi_xprt_set_irq_mode(struct edge_info *einfo)
264{
265 unsigned long flags;
266
267 spin_lock_irqsave(&einfo->activity_lock, flags);
268 einfo->activity_flag &= ~ACTIVE_RX;
269 spin_unlock_irqrestore(&einfo->activity_lock, flags);
270}
271
272/**
273 * glink_spi_xprt_rx_data() - Receive data over SPI bus
274 * @einfo: Edge from which the data has to be received.
275 * @src: Source Address of the RX data.
276 * @dst: Address of the destination RX buffer.
277 * @size: Size of the RX data.
278 *
279 * This function is used to receive data or command as a byte stream from
280 * the remote subsystem over the SPI bus.
281 *
282 * Return: 0 on success, standard Linux error codes on failure.
283 */
284static int glink_spi_xprt_rx_data(struct edge_info *einfo, void *src,
285 void *dst, uint32_t size)
286{
287 struct wcd_spi_msg spi_msg;
288
Chris Lewbb58f022017-06-27 16:54:11 -0700289 if (unlikely(!einfo->spi_ops.read_dev))
290 return -EINVAL;
291
Chris Lewfa6135e2016-08-01 13:29:46 -0700292 memset(&spi_msg, 0, sizeof(spi_msg));
293 spi_msg.data = dst;
294 spi_msg.remote_addr = (uint32_t)(size_t)src;
295 spi_msg.len = (size_t)size;
Chris Lewbb58f022017-06-27 16:54:11 -0700296 return einfo->spi_ops.read_dev(einfo->spi_ops.spi_dev, &spi_msg);
Chris Lewfa6135e2016-08-01 13:29:46 -0700297}
298
299/**
300 * glink_spi_xprt_tx_data() - Transmit data over SPI bus
301 * @einfo: Edge from which the data has to be received.
302 * @src: Address of the TX buffer.
303 * @dst: Destination Address of the TX Date.
304 * @size: Size of the TX data.
305 *
306 * This function is used to transmit data or command as a byte stream to
307 * the remote subsystem over the SPI bus.
308 *
309 * Return: 0 on success, standard Linux error codes on failure.
310 */
311static int glink_spi_xprt_tx_data(struct edge_info *einfo, void *src,
312 void *dst, uint32_t size)
313{
314 struct wcd_spi_msg spi_msg;
315
Chris Lewbb58f022017-06-27 16:54:11 -0700316 if (unlikely(!einfo->spi_ops.write_dev))
317 return -EINVAL;
318
Chris Lewfa6135e2016-08-01 13:29:46 -0700319 memset(&spi_msg, 0, sizeof(spi_msg));
320 spi_msg.data = src;
321 spi_msg.remote_addr = (uint32_t)(size_t)dst;
322 spi_msg.len = (size_t)size;
Chris Lewbb58f022017-06-27 16:54:11 -0700323 return einfo->spi_ops.write_dev(einfo->spi_ops.spi_dev, &spi_msg);
Chris Lewfa6135e2016-08-01 13:29:46 -0700324}
325
326/**
327 * glink_spi_xprt_reg_read() - Read the TX/RX FIFO Read/Write Index registers
328 * @einfo: Edge from which the registers have to be read.
329 * @reg_addr: Address of the register to be read.
330 * @data: Buffer into which the register data has to be read.
331 *
332 * Return: 0 on success, standard Linux error codes on failure.
333 */
334static int glink_spi_xprt_reg_read(struct edge_info *einfo, u32 reg_addr,
335 uint32_t *data)
336{
337 int rc;
338
339 rc = glink_spi_xprt_rx_data(einfo, (void *)(unsigned long)reg_addr,
340 data, sizeof(*data));
341 if (!rc)
342 *data = *data & ID_MASK;
343 return rc;
344}
345
346/**
347 * glink_spi_xprt_reg_write() - Write the TX/RX FIFO Read/Write Index registers
348 * @einfo: Edge to which the registers have to be written.
349 * @reg_addr: Address of the registers to be written.
350 * @data: Data to be written to the registers.
351 *
352 * Return: 0 on success, standard Linux error codes on failure.
353 */
354static int glink_spi_xprt_reg_write(struct edge_info *einfo, u32 reg_addr,
355 uint32_t data)
356{
357 return glink_spi_xprt_tx_data(einfo, &data,
358 (void *)(unsigned long)reg_addr, sizeof(data));
359}
360
361/**
362 * glink_spi_xprt_write_avail() - Available Write Space in the remote side
363 * @einfo: Edge information corresponding to the remote side.
364 *
365 * This function reads the TX FIFO Read & Write Index registers from the
366 * remote subsystem and calculate the available write space.
367 *
368 * Return: 0 on error, available write space on success.
369 */
370static int glink_spi_xprt_write_avail(struct edge_info *einfo)
371{
372 uint32_t read_id;
373 uint32_t write_id;
374 int write_avail;
375 int ret;
376
377 ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_read_reg_addr,
378 &read_id);
379 if (ret < 0) {
380 pr_err("%s: Error %d reading %s tx_fifo_read_reg_addr %d\n",
381 __func__, ret, einfo->xprt_cfg.edge,
382 einfo->tx_fifo_read_reg_addr);
383 return 0;
384 }
385
386 ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_write_reg_addr,
387 &write_id);
388 if (ret < 0) {
389 pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n",
390 __func__, ret, einfo->xprt_cfg.edge,
391 einfo->tx_fifo_write_reg_addr);
392 return 0;
393 }
394
395 if (!read_id || !write_id)
396 return 0;
397
398 if (unlikely(!einfo->tx_fifo_start))
399 einfo->tx_fifo_start = write_id;
400
401 if (read_id > write_id)
402 write_avail = read_id - write_id;
403 else
404 write_avail = einfo->fifo_size - (write_id - read_id);
405
406 if (write_avail < FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE)
407 write_avail = 0;
408 else
409 write_avail -= FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE;
410
411 return write_avail;
412}
413
414/**
415 * glink_spi_xprt_read_avail() - Available Read Data from the remote side
416 * @einfo: Edge information corresponding to the remote side.
417 *
418 * This function reads the RX FIFO Read & Write Index registers from the
419 * remote subsystem and calculate the available read data size.
420 *
421 * Return: 0 on error, available read data on success.
422 */
423static int glink_spi_xprt_read_avail(struct edge_info *einfo)
424{
425 uint32_t read_id;
426 uint32_t write_id;
427 int read_avail;
428 int ret;
429
430 ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_read_reg_addr,
431 &read_id);
432 if (ret < 0) {
433 pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n",
434 __func__, ret, einfo->xprt_cfg.edge,
435 einfo->rx_fifo_read_reg_addr);
436 return 0;
437 }
438
439 ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_write_reg_addr,
440 &write_id);
441 if (ret < 0) {
442 pr_err("%s: Error %d reading %s rx_fifo_write_reg_addr %d\n",
443 __func__, ret, einfo->xprt_cfg.edge,
444 einfo->rx_fifo_write_reg_addr);
445 return 0;
446 }
447
448 if (!read_id || !write_id)
449 return 0;
450
451 if (unlikely(!einfo->rx_fifo_start))
452 einfo->rx_fifo_start = read_id;
453
454 if (read_id <= write_id)
455 read_avail = write_id - read_id;
456 else
457 read_avail = einfo->fifo_size - (read_id - write_id);
458 return read_avail;
459}
460
461/**
462 * glink_spi_xprt_rx_cmd() - Receive G-Link commands
463 * @einfo: Edge information corresponding to the remote side.
464 * @dst: Destination buffer where the commands have to be read into.
465 * @size: Size of the data to be read.
466 *
467 * This function is used to receive the commands from the RX FIFO. This
468 * function updates the RX FIFO Read Index after reading the data.
469 *
470 * Return: 0 on success, standard Linux error codes on error.
471 */
472static int glink_spi_xprt_rx_cmd(struct edge_info *einfo, void *dst,
473 uint32_t size)
474{
475 uint32_t read_id;
476 uint32_t size_to_read = size;
477 uint32_t offset = 0;
478 int ret;
479
480 ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_read_reg_addr,
481 &read_id);
482 if (ret < 0) {
483 pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n",
484 __func__, ret, einfo->xprt_cfg.edge,
485 einfo->rx_fifo_read_reg_addr);
486 return ret;
487 }
488
489 do {
490 if ((read_id + size_to_read) >=
491 (einfo->rx_fifo_start + einfo->fifo_size))
492 size_to_read = einfo->rx_fifo_start + einfo->fifo_size
493 - read_id;
494 ret = glink_spi_xprt_rx_data(einfo, (void *)(size_t)read_id,
495 dst + offset, size_to_read);
496 if (ret < 0) {
497 pr_err("%s: Error %d reading data\n", __func__, ret);
498 return ret;
499 }
500 read_id += size_to_read;
501 offset += size_to_read;
502 if (read_id >= (einfo->rx_fifo_start + einfo->fifo_size))
503 read_id = einfo->rx_fifo_start;
504 size_to_read = size - offset;
505 } while (size_to_read);
506
507 ret = glink_spi_xprt_reg_write(einfo, einfo->rx_fifo_read_reg_addr,
508 read_id);
509 if (ret < 0)
510 pr_err("%s: Error %d writing %s rx_fifo_read_reg_addr %d\n",
511 __func__, ret, einfo->xprt_cfg.edge,
512 einfo->rx_fifo_read_reg_addr);
513 return ret;
514}
515
516/**
517 * glink_spi_xprt_tx_cmd_safe() - Transmit G-Link commands
518 * @einfo: Edge information corresponding to the remote subsystem.
519 * @src: Source buffer containing the G-Link command.
520 * @size: Size of the command to transmit.
521 *
522 * This function is used to transmit the G-Link commands. This function
523 * must be called with einfo->write_lock locked.
524 *
525 * Return: 0 on success, standard Linux error codes on error.
526 */
527static int glink_spi_xprt_tx_cmd_safe(struct edge_info *einfo, void *src,
528 uint32_t size)
529{
530 uint32_t write_id;
531 uint32_t size_to_write = size;
532 uint32_t offset = 0;
533 int ret;
534
535 ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_write_reg_addr,
536 &write_id);
537 if (ret < 0) {
538 pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n",
539 __func__, ret, einfo->xprt_cfg.edge,
540 einfo->tx_fifo_write_reg_addr);
541 return ret;
542 }
543
544 do {
545 if ((write_id + size_to_write) >=
546 (einfo->tx_fifo_start + einfo->fifo_size))
547 size_to_write = einfo->tx_fifo_start + einfo->fifo_size
548 - write_id;
549 ret = glink_spi_xprt_tx_data(einfo, src + offset,
550 (void *)(size_t)write_id, size_to_write);
551 if (ret < 0) {
552 pr_err("%s: Error %d writing data\n", __func__, ret);
553 return ret;
554 }
555 write_id += size_to_write;
556 offset += size_to_write;
557 if (write_id >= (einfo->tx_fifo_start + einfo->fifo_size))
558 write_id = einfo->tx_fifo_start;
559 size_to_write = size - offset;
560 } while (size_to_write);
561
562 ret = glink_spi_xprt_reg_write(einfo, einfo->tx_fifo_write_reg_addr,
563 write_id);
564 if (ret < 0)
565 pr_err("%s: Error %d writing %s tx_fifo_write_reg_addr %d\n",
566 __func__, ret, einfo->xprt_cfg.edge,
567 einfo->tx_fifo_write_reg_addr);
568 return ret;
569}
570
571/**
572 * send_tx_blocked_signal() - Send flow control request message
573 * @einfo: Edge information corresponding to the remote subsystem.
574 *
575 * This function is used to send a message to the remote subsystem indicating
576 * that the local subsystem is waiting for the write space. The remote
577 * subsystem on receiving this message will send a resume tx message.
578 */
579static void send_tx_blocked_signal(struct edge_info *einfo)
580{
581 struct read_notif_request {
582 uint16_t cmd;
583 uint16_t reserved;
584 uint32_t reserved2;
585 uint64_t reserved3;
586 };
587 struct read_notif_request read_notif_req = {0};
588
589 read_notif_req.cmd = READ_NOTIF_CMD;
590
591 if (!einfo->tx_blocked_signal_sent) {
592 einfo->tx_blocked_signal_sent = true;
593 glink_spi_xprt_tx_cmd_safe(einfo, &read_notif_req,
594 sizeof(read_notif_req));
595 }
596}
597
598/**
599 * glink_spi_xprt_tx_cmd() - Transmit G-Link commands
600 * @einfo: Edge information corresponding to the remote subsystem.
601 * @src: Source buffer containing the G-Link command.
602 * @size: Size of the command to transmit.
603 *
604 * This function is used to transmit the G-Link commands. This function
605 * might sleep if the space is not available to transmit the command.
606 *
607 * Return: 0 on success, standard Linux error codes on error.
608 */
609static int glink_spi_xprt_tx_cmd(struct edge_info *einfo, void *src,
610 uint32_t size)
611{
612 int ret;
613 DEFINE_WAIT(wait);
614
615 mutex_lock(&einfo->write_lock);
616 while (glink_spi_xprt_write_avail(einfo) < size) {
617 send_tx_blocked_signal(einfo);
618 prepare_to_wait(&einfo->tx_blocked_queue, &wait,
619 TASK_UNINTERRUPTIBLE);
620 if (glink_spi_xprt_write_avail(einfo) < size &&
621 !einfo->in_ssr) {
622 mutex_unlock(&einfo->write_lock);
623 schedule();
624 mutex_lock(&einfo->write_lock);
625 }
626 finish_wait(&einfo->tx_blocked_queue, &wait);
627 if (einfo->in_ssr) {
628 mutex_unlock(&einfo->write_lock);
629 return -EFAULT;
630 }
631 }
632 ret = glink_spi_xprt_tx_cmd_safe(einfo, src, size);
633 mutex_unlock(&einfo->write_lock);
634 return ret;
635}
636
637/**
638 * process_rx_data() - process received data from an edge
639 * @einfo: The edge the data is received on.
640 * @cmd_id: ID to specify the type of data.
641 * @rcid: The remote channel id associated with the data.
642 * @intend_id: The intent the data should be put in.
643 * @src: Address of the source buffer from which the data
644 * is read.
645 * @frag_size: Size of the data fragment to read.
646 * @size_remaining: Size of data left to be read in this packet.
647 */
648static void process_rx_data(struct edge_info *einfo, uint16_t cmd_id,
649 uint32_t rcid, uint32_t intent_id, void *src,
650 uint32_t frag_size, uint32_t size_remaining)
651{
652 struct glink_core_rx_intent *intent;
653 int rc = 0;
654
655 intent = einfo->xprt_if.glink_core_if_ptr->rx_get_pkt_ctx(
656 &einfo->xprt_if, rcid, intent_id);
657 if (intent == NULL) {
658 GLINK_ERR("%s: no intent for ch %d liid %d\n", __func__, rcid,
659 intent_id);
660 return;
661 } else if (intent->data == NULL) {
662 GLINK_ERR("%s: intent for ch %d liid %d has no data buff\n",
663 __func__, rcid, intent_id);
664 return;
665 } else if (intent->intent_size - intent->write_offset < frag_size ||
666 intent->write_offset + size_remaining > intent->intent_size) {
667 GLINK_ERR("%s: rx data size:%d and remaining:%d %s %d %s:%d\n",
668 __func__, frag_size, size_remaining,
669 "will overflow ch", rcid, "intent", intent_id);
670 return;
671 }
672
673 if (cmd_id == TX_SHORT_DATA_CMD)
674 memcpy(intent->data + intent->write_offset, src, frag_size);
675 else
676 rc = glink_spi_xprt_rx_data(einfo, src,
677 intent->data + intent->write_offset, frag_size);
678 if (rc < 0) {
679 GLINK_ERR("%s: Error %d receiving data %d:%d:%d:%d\n",
680 __func__, rc, rcid, intent_id, frag_size,
681 size_remaining);
682 size_remaining += frag_size;
683 } else {
684 intent->write_offset += frag_size;
685 intent->pkt_size += frag_size;
686
687 if (unlikely((cmd_id == TRACER_PKT_CMD ||
688 cmd_id == TRACER_PKT_CONT_CMD) && !size_remaining)) {
689 tracer_pkt_log_event(intent->data, GLINK_XPRT_RX);
690 intent->tracer_pkt = true;
691 }
692 }
693 einfo->xprt_if.glink_core_if_ptr->rx_put_pkt_ctx(&einfo->xprt_if,
694 rcid, intent, size_remaining ? false : true);
695}
696
697/**
698 * process_rx_cmd() - Process incoming G-Link commands
699 * @einfo: Edge information corresponding to the remote subsystem.
700 * @rx_data: Buffer which contains the G-Link commands to be processed.
701 * @rx_size: Size of the buffer containing the series of G-Link commands.
702 *
703 * This function is used to parse and process a series of G-Link commands
704 * received in a buffer.
705 */
706static void process_rx_cmd(struct edge_info *einfo,
707 void *rx_data, int rx_size)
708{
709 struct command {
710 uint16_t id;
711 uint16_t param1;
712 uint32_t param2;
713 uint32_t param3;
714 uint32_t param4;
715 };
716 struct intent_desc {
717 uint32_t size;
718 uint32_t id;
719 uint64_t addr;
720 };
721 struct rx_desc {
722 uint32_t size;
723 uint32_t size_left;
724 uint64_t addr;
725 };
726 struct rx_short_data_desc {
727 unsigned char data[SHORT_PKT_SIZE];
728 };
729 struct command *cmd;
730 struct intent_desc *intents;
731 struct rx_desc *rx_descp;
732 struct rx_short_data_desc *rx_sd_descp;
733 int offset = 0;
734 int rcu_id;
735 uint16_t rcid;
736 uint16_t name_len;
737 uint16_t prio;
738 char *name;
739 bool granted;
740 int i;
741
742 rcu_id = srcu_read_lock(&einfo->use_ref);
743 if (einfo->in_ssr) {
744 srcu_read_unlock(&einfo->use_ref, rcu_id);
745 return;
746 }
747
748 while (offset < rx_size) {
749 cmd = (struct command *)(rx_data + offset);
750 offset += sizeof(*cmd);
751 switch (cmd->id) {
752 case VERSION_CMD:
753 if (cmd->param3)
754 einfo->fifo_size = cmd->param3;
755 einfo->xprt_if.glink_core_if_ptr->rx_cmd_version(
756 &einfo->xprt_if, cmd->param1, cmd->param2);
757 break;
758
759 case VERSION_ACK_CMD:
760 einfo->xprt_if.glink_core_if_ptr->rx_cmd_version_ack(
761 &einfo->xprt_if, cmd->param1, cmd->param2);
762 break;
763
764 case OPEN_CMD:
765 rcid = cmd->param1;
766 name_len = (uint16_t)(cmd->param2 & 0xFFFF);
767 prio = (uint16_t)((cmd->param2 & 0xFFFF0000) >> 16);
768 name = (char *)(rx_data + offset);
769 offset += ALIGN(name_len, FIFO_ALIGNMENT);
770 einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_remote_open(
771 &einfo->xprt_if, rcid, name, prio);
772 break;
773
774 case CLOSE_CMD:
775 einfo->xprt_if.glink_core_if_ptr->
776 rx_cmd_ch_remote_close(
777 &einfo->xprt_if, cmd->param1);
778 break;
779
780 case OPEN_ACK_CMD:
781 prio = (uint16_t)(cmd->param2 & 0xFFFF);
782 einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_open_ack(
783 &einfo->xprt_if, cmd->param1, prio);
784 break;
785
786 case CLOSE_ACK_CMD:
787 einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_close_ack(
788 &einfo->xprt_if, cmd->param1);
789 break;
790
791 case RX_INTENT_CMD:
792 for (i = 0; i < cmd->param2; i++) {
793 intents = (struct intent_desc *)
794 (rx_data + offset);
795 offset += sizeof(*intents);
796 einfo->xprt_if.glink_core_if_ptr->
797 rx_cmd_remote_rx_intent_put_cookie(
Dhoat Harpaldf33d122017-01-05 18:51:00 +0530798 &einfo->xprt_if, cmd->param1,
799 intents->id, intents->size,
800 (void *)(uintptr_t)(intents->addr));
Chris Lewfa6135e2016-08-01 13:29:46 -0700801 }
802 break;
803
804 case RX_DONE_CMD:
805 einfo->xprt_if.glink_core_if_ptr->rx_cmd_tx_done(
806 &einfo->xprt_if, cmd->param1, cmd->param2,
807 false);
808 break;
809
810 case RX_INTENT_REQ_CMD:
811 einfo->xprt_if.glink_core_if_ptr->
812 rx_cmd_remote_rx_intent_req(
813 &einfo->xprt_if, cmd->param1,
814 cmd->param2);
815 break;
816
817 case RX_INTENT_REQ_ACK_CMD:
818 granted = cmd->param2 == 1 ? true : false;
819 einfo->xprt_if.glink_core_if_ptr->
820 rx_cmd_rx_intent_req_ack(&einfo->xprt_if,
821 cmd->param1, granted);
822 break;
823
824 case TX_DATA_CMD:
825 case TX_DATA_CONT_CMD:
826 case TRACER_PKT_CMD:
827 case TRACER_PKT_CONT_CMD:
828 rx_descp = (struct rx_desc *)(rx_data + offset);
829 offset += sizeof(*rx_descp);
Dhoat Harpaldf33d122017-01-05 18:51:00 +0530830 process_rx_data(einfo, cmd->id, cmd->param1,
831 cmd->param2,
832 (void *)(uintptr_t)(rx_descp->addr),
833 rx_descp->size, rx_descp->size_left);
Chris Lewfa6135e2016-08-01 13:29:46 -0700834 break;
835
836 case TX_SHORT_DATA_CMD:
837 rx_sd_descp = (struct rx_short_data_desc *)
838 (rx_data + offset);
839 offset += sizeof(*rx_sd_descp);
840 process_rx_data(einfo, cmd->id, cmd->param1,
841 cmd->param2, (void *)rx_sd_descp->data,
842 cmd->param3, cmd->param4);
843 break;
844
845 case READ_NOTIF_CMD:
846 break;
847
848 case SIGNALS_CMD:
849 einfo->xprt_if.glink_core_if_ptr->rx_cmd_remote_sigs(
850 &einfo->xprt_if, cmd->param1, cmd->param2);
851 break;
852
853 case RX_DONE_W_REUSE_CMD:
854 einfo->xprt_if.glink_core_if_ptr->rx_cmd_tx_done(
855 &einfo->xprt_if, cmd->param1,
856 cmd->param2, true);
857 break;
858
859 default:
860 pr_err("Unrecognized command: %d\n", cmd->id);
861 break;
862 }
863 }
864 srcu_read_unlock(&einfo->use_ref, rcu_id);
865}
866
867/**
868 * __rx_worker() - Receive commands on a specific edge
869 * @einfo: Edge to process commands on.
870 *
871 * This function checks the size of data to be received, allocates the
872 * buffer for that data and reads the data from the remote subsytem
873 * into that buffer. This function then calls the process_rx_cmd() to
874 * parse the received G-Link command sequence. This function will also
875 * poll for the data for a predefined duration for performance reasons.
876 */
877static void __rx_worker(struct edge_info *einfo)
878{
879 uint32_t inactive_cycles = 0;
880 int rx_avail, rc;
881 void *rx_data;
882 int rcu_id;
883
884 rcu_id = srcu_read_lock(&einfo->use_ref);
Karthikeyan Ramasubramaniane03039d2016-09-26 17:30:08 -0600885 if (einfo->in_ssr) {
886 srcu_read_unlock(&einfo->use_ref, rcu_id);
887 return;
888 }
889
Chris Lewfa6135e2016-08-01 13:29:46 -0700890 if (unlikely(!einfo->rx_fifo_start)) {
891 rx_avail = glink_spi_xprt_read_avail(einfo);
892 if (!rx_avail) {
893 srcu_read_unlock(&einfo->use_ref, rcu_id);
894 return;
895 }
Chris Lewfa6135e2016-08-01 13:29:46 -0700896 einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if);
897 }
898
Chris Lewfa6135e2016-08-01 13:29:46 -0700899 glink_spi_xprt_set_poll_mode(einfo);
Chris Lew67057ff2017-01-23 16:36:43 -0800900 do {
Chris Lewfa6135e2016-08-01 13:29:46 -0700901 if (einfo->tx_resume_needed &&
902 glink_spi_xprt_write_avail(einfo)) {
903 einfo->tx_resume_needed = false;
904 einfo->xprt_if.glink_core_if_ptr->tx_resume(
905 &einfo->xprt_if);
906 }
907 mutex_lock(&einfo->write_lock);
908 if (einfo->tx_blocked_signal_sent) {
909 wake_up_all(&einfo->tx_blocked_queue);
910 einfo->tx_blocked_signal_sent = false;
911 }
912 mutex_unlock(&einfo->write_lock);
913
914 rx_avail = glink_spi_xprt_read_avail(einfo);
915 if (!rx_avail) {
916 usleep_range(POLL_INTERVAL_US, POLL_INTERVAL_US + 50);
917 inactive_cycles++;
918 continue;
919 }
920 inactive_cycles = 0;
921
922 rx_data = kzalloc(rx_avail, GFP_KERNEL);
923 if (!rx_data)
924 break;
925
926 rc = glink_spi_xprt_rx_cmd(einfo, rx_data, rx_avail);
927 if (rc < 0) {
928 GLINK_ERR("%s: Error %d receiving data\n",
929 __func__, rc);
930 kfree(rx_data);
931 break;
932 }
933 process_rx_cmd(einfo, rx_data, rx_avail);
934 kfree(rx_data);
Chris Lew67057ff2017-01-23 16:36:43 -0800935 } while (inactive_cycles < MAX_INACTIVE_CYCLES && !einfo->in_ssr);
Chris Lewfa6135e2016-08-01 13:29:46 -0700936 glink_spi_xprt_set_irq_mode(einfo);
937 srcu_read_unlock(&einfo->use_ref, rcu_id);
938}
939
940/**
941 * rx_worker() - Worker function to process received commands
942 * @work: kwork associated with the edge to process commands on.
943 */
944static void rx_worker(struct kthread_work *work)
945{
946 struct edge_info *einfo;
947
948 einfo = container_of(work, struct edge_info, kwork);
949 __rx_worker(einfo);
950};
951
952/**
953 * tx_cmd_version() - Convert a version cmd to wire format and transmit
954 * @if_ptr: The transport to transmit on.
955 * @version: The version number to encode.
956 * @features: The features information to encode.
957 */
958static void tx_cmd_version(struct glink_transport_if *if_ptr, uint32_t version,
959 uint32_t features)
960{
961 struct command {
962 uint16_t id;
963 uint16_t version;
964 uint32_t features;
965 uint32_t fifo_size;
966 uint32_t reserved;
967 };
968 struct command cmd;
969 struct edge_info *einfo;
970 int rcu_id;
971
972 memset(&cmd, 0, sizeof(cmd));
973 einfo = container_of(if_ptr, struct edge_info, xprt_if);
974
975 rcu_id = srcu_read_lock(&einfo->use_ref);
976 if (einfo->in_ssr) {
977 srcu_read_unlock(&einfo->use_ref, rcu_id);
978 return;
979 }
980
981 cmd.id = VERSION_CMD;
982 cmd.version = version;
983 cmd.features = features;
984
985 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
986 srcu_read_unlock(&einfo->use_ref, rcu_id);
987}
988
989/**
990 * tx_cmd_version_ack() - Convert a version ack cmd to wire format and transmit
991 * @if_ptr: The transport to transmit on.
992 * @version: The version number to encode.
993 * @features: The features information to encode.
994 */
995static void tx_cmd_version_ack(struct glink_transport_if *if_ptr,
996 uint32_t version,
997 uint32_t features)
998{
999 struct command {
1000 uint16_t id;
1001 uint16_t version;
1002 uint32_t features;
1003 uint32_t fifo_size;
1004 uint32_t reserved;
1005 };
1006 struct command cmd;
1007 struct edge_info *einfo;
1008 int rcu_id;
1009
1010 memset(&cmd, 0, sizeof(cmd));
1011 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1012
1013 rcu_id = srcu_read_lock(&einfo->use_ref);
1014 if (einfo->in_ssr) {
1015 srcu_read_unlock(&einfo->use_ref, rcu_id);
1016 return;
1017 }
1018
1019 cmd.id = VERSION_ACK_CMD;
1020 cmd.version = version;
1021 cmd.features = features;
1022
1023 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1024 srcu_read_unlock(&einfo->use_ref, rcu_id);
1025}
1026
1027/**
1028 * set_version() - Activate a negotiated version and feature set
1029 * @if_ptr: The transport to configure.
1030 * @version: The version to use.
1031 * @features: The features to use.
1032 *
1033 * Return: The supported capabilities of the transport.
1034 */
1035static uint32_t set_version(struct glink_transport_if *if_ptr, uint32_t version,
1036 uint32_t features)
1037{
1038 struct edge_info *einfo;
1039 uint32_t ret;
1040 int rcu_id;
1041
1042 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1043
1044 rcu_id = srcu_read_lock(&einfo->use_ref);
1045 if (einfo->in_ssr) {
1046 srcu_read_unlock(&einfo->use_ref, rcu_id);
1047 return 0;
1048 }
1049
1050 ret = GCAP_SIGNALS;
1051 if (features & TRACER_PKT_FEATURE)
1052 ret |= GCAP_TRACER_PKT;
1053
1054 srcu_read_unlock(&einfo->use_ref, rcu_id);
1055 return ret;
1056}
1057
1058/**
1059 * tx_cmd_ch_open() - Convert a channel open cmd to wire format and transmit
1060 * @if_ptr: The transport to transmit on.
1061 * @lcid: The local channel id to encode.
1062 * @name: The channel name to encode.
1063 * @req_xprt: The transport the core would like to migrate this channel to.
1064 *
1065 * Return: 0 on success or standard Linux error code.
1066 */
1067static int tx_cmd_ch_open(struct glink_transport_if *if_ptr, uint32_t lcid,
1068 const char *name, uint16_t req_xprt)
1069{
1070 struct command {
1071 uint16_t id;
1072 uint16_t lcid;
1073 uint16_t length;
1074 uint16_t req_xprt;
1075 uint64_t reserved;
1076 };
1077 struct command cmd;
1078 struct edge_info *einfo;
1079 uint32_t buf_size;
1080 void *buf;
1081 int rcu_id;
1082
1083 memset(&cmd, 0, sizeof(cmd));
1084 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1085
1086 rcu_id = srcu_read_lock(&einfo->use_ref);
1087 if (einfo->in_ssr) {
1088 srcu_read_unlock(&einfo->use_ref, rcu_id);
1089 return -EFAULT;
1090 }
1091
1092 cmd.id = OPEN_CMD;
1093 cmd.lcid = lcid;
1094 cmd.length = (uint16_t)(strlen(name) + 1);
1095 cmd.req_xprt = req_xprt;
1096
1097 buf_size = ALIGN(sizeof(cmd) + cmd.length, FIFO_ALIGNMENT);
1098
1099 buf = kzalloc(buf_size, GFP_KERNEL);
1100 if (!buf) {
1101 srcu_read_unlock(&einfo->use_ref, rcu_id);
1102 return -ENOMEM;
1103 }
1104
1105 memcpy(buf, &cmd, sizeof(cmd));
1106 memcpy(buf + sizeof(cmd), name, cmd.length);
1107
1108 glink_spi_xprt_tx_cmd(einfo, buf, buf_size);
1109
1110 kfree(buf);
1111 srcu_read_unlock(&einfo->use_ref, rcu_id);
1112 return 0;
1113}
1114
1115/**
1116 * tx_cmd_ch_close() - Convert a channel close cmd to wire format and transmit
1117 * @if_ptr: The transport to transmit on.
1118 * @lcid: The local channel id to encode.
1119 *
1120 * Return: 0 on success or standard Linux error code.
1121 */
1122static int tx_cmd_ch_close(struct glink_transport_if *if_ptr, uint32_t lcid)
1123{
1124 struct command {
1125 uint16_t id;
1126 uint16_t lcid;
1127 uint32_t reserved1;
1128 uint64_t reserved2;
1129 };
1130 struct command cmd;
1131 struct edge_info *einfo;
1132 int rcu_id;
1133
1134 memset(&cmd, 0, sizeof(cmd));
1135 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1136
1137 rcu_id = srcu_read_lock(&einfo->use_ref);
1138 if (einfo->in_ssr) {
1139 srcu_read_unlock(&einfo->use_ref, rcu_id);
1140 return -EFAULT;
1141 }
1142
1143 cmd.id = CLOSE_CMD;
1144 cmd.lcid = lcid;
1145
1146 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1147
1148 srcu_read_unlock(&einfo->use_ref, rcu_id);
1149 return 0;
1150}
1151
1152/**
1153 * tx_cmd_ch_remote_open_ack() - Convert a channel open ack cmd to wire format
1154 * and transmit
1155 * @if_ptr: The transport to transmit on.
1156 * @rcid: The remote channel id to encode.
1157 * @xprt_resp: The response to a transport migration request.
1158 */
1159static void tx_cmd_ch_remote_open_ack(struct glink_transport_if *if_ptr,
1160 uint32_t rcid, uint16_t xprt_resp)
1161{
1162 struct command {
1163 uint16_t id;
1164 uint16_t rcid;
1165 uint16_t reserved1;
1166 uint16_t xprt_resp;
1167 uint64_t reserved2;
1168 };
1169 struct command cmd;
1170 struct edge_info *einfo;
1171 int rcu_id;
1172
1173 memset(&cmd, 0, sizeof(cmd));
1174 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1175
1176 rcu_id = srcu_read_lock(&einfo->use_ref);
1177 if (einfo->in_ssr) {
1178 srcu_read_unlock(&einfo->use_ref, rcu_id);
1179 return;
1180 }
1181
1182 cmd.id = OPEN_ACK_CMD;
1183 cmd.rcid = rcid;
1184 cmd.xprt_resp = xprt_resp;
1185
1186 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1187 srcu_read_unlock(&einfo->use_ref, rcu_id);
1188}
1189
1190/**
1191 * tx_cmd_ch_remote_close_ack() - Convert a channel close ack cmd to wire format
1192 * and transmit
1193 * @if_ptr: The transport to transmit on.
1194 * @rcid: The remote channel id to encode.
1195 */
1196static void tx_cmd_ch_remote_close_ack(struct glink_transport_if *if_ptr,
1197 uint32_t rcid)
1198{
1199 struct command {
1200 uint16_t id;
1201 uint16_t rcid;
1202 uint32_t reserved1;
1203 uint64_t reserved2;
1204 };
1205 struct command cmd;
1206 struct edge_info *einfo;
1207 int rcu_id;
1208
1209 memset(&cmd, 0, sizeof(cmd));
1210 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1211
1212 rcu_id = srcu_read_lock(&einfo->use_ref);
1213 if (einfo->in_ssr) {
1214 srcu_read_unlock(&einfo->use_ref, rcu_id);
1215 return;
1216 }
1217
1218 cmd.id = CLOSE_ACK_CMD;
1219 cmd.rcid = rcid;
1220
1221 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1222 srcu_read_unlock(&einfo->use_ref, rcu_id);
1223}
1224
1225/**
1226 * ssr() - Process a subsystem restart notification of a transport
1227 * @if_ptr: The transport to restart
1228 *
1229 * Return: 0 on success or standard Linux error code.
1230 */
1231static int ssr(struct glink_transport_if *if_ptr)
1232{
1233 struct edge_info *einfo;
1234
1235 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1236
1237 einfo->in_ssr = true;
1238 wake_up_all(&einfo->tx_blocked_queue);
1239
1240 synchronize_srcu(&einfo->use_ref);
1241 einfo->tx_resume_needed = false;
1242 einfo->tx_blocked_signal_sent = false;
1243 einfo->tx_fifo_start = 0;
1244 einfo->rx_fifo_start = 0;
1245 einfo->fifo_size = DEFAULT_FIFO_SIZE;
1246 einfo->xprt_if.glink_core_if_ptr->link_down(&einfo->xprt_if);
1247
1248 return 0;
1249}
1250
1251/**
1252 * allocate_rx_intent() - Allocate/reserve space for RX Intent
1253 * @if_ptr: The transport the intent is associated with.
1254 * @size: size of intent.
1255 * @intent: Pointer to the intent structure.
1256 *
1257 * Assign "data" with the buffer created, since the transport creates
1258 * a linear buffer and "iovec" with the "intent" itself, so that
1259 * the data can be passed to a client that receives only vector buffer.
1260 * Note that returning NULL for the pointer is valid (it means that space has
1261 * been reserved, but the actual pointer will be provided later).
1262 *
1263 * Return: 0 on success or standard Linux error code.
1264 */
1265static int allocate_rx_intent(struct glink_transport_if *if_ptr, size_t size,
1266 struct glink_core_rx_intent *intent)
1267{
1268 void *t;
1269
1270 t = kzalloc(size, GFP_KERNEL);
1271 if (!t)
1272 return -ENOMEM;
1273
1274 intent->data = t;
1275 intent->iovec = (void *)intent;
1276 intent->vprovider = rx_linear_vbuf_provider;
1277 intent->pprovider = NULL;
1278 return 0;
1279}
1280
1281/**
1282 * deallocate_rx_intent() - Deallocate space created for RX Intent
1283 * @if_ptr: The transport the intent is associated with.
1284 * @intent: Pointer to the intent structure.
1285 *
1286 * Return: 0 on success or standard Linux error code.
1287 */
1288static int deallocate_rx_intent(struct glink_transport_if *if_ptr,
1289 struct glink_core_rx_intent *intent)
1290{
1291 if (!intent || !intent->data)
1292 return -EINVAL;
1293
1294 kfree(intent->data);
1295 intent->data = NULL;
1296 intent->iovec = NULL;
1297 intent->vprovider = NULL;
1298 return 0;
1299}
1300
1301/**
1302 * tx_cmd_local_rx_intent() - Convert an rx intent cmd to wire format and
1303 * transmit
1304 * @if_ptr: The transport to transmit on.
1305 * @lcid: The local channel id to encode.
1306 * @size: The intent size to encode.
1307 * @liid: The local intent id to encode.
1308 *
1309 * Return: 0 on success or standard Linux error code.
1310 */
1311static int tx_cmd_local_rx_intent(struct glink_transport_if *if_ptr,
1312 uint32_t lcid, size_t size, uint32_t liid)
1313{
1314 struct command {
1315 uint16_t id;
1316 uint16_t lcid;
1317 uint32_t count;
1318 uint64_t reserved;
1319 uint32_t size;
1320 uint32_t liid;
1321 uint64_t addr;
1322 };
1323 struct command cmd;
1324 struct edge_info *einfo;
1325 int rcu_id;
1326
1327 if (size > UINT_MAX) {
1328 pr_err("%s: size %zu is too large to encode\n", __func__, size);
1329 return -EMSGSIZE;
1330 }
1331
1332 memset(&cmd, 0, sizeof(cmd));
1333 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1334
1335 rcu_id = srcu_read_lock(&einfo->use_ref);
1336 if (einfo->in_ssr) {
1337 srcu_read_unlock(&einfo->use_ref, rcu_id);
1338 return -EFAULT;
1339 }
1340
1341 cmd.id = RX_INTENT_CMD;
1342 cmd.lcid = lcid;
1343 cmd.count = 1;
1344 cmd.size = size;
1345 cmd.liid = liid;
1346
1347 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1348
1349 srcu_read_unlock(&einfo->use_ref, rcu_id);
1350 return 0;
1351}
1352
1353/**
1354 * tx_cmd_local_rx_done() - Convert an rx done cmd to wire format and transmit
1355 * @if_ptr: The transport to transmit on.
1356 * @lcid: The local channel id to encode.
1357 * @liid: The local intent id to encode.
1358 * @reuse: Reuse the consumed intent.
1359 */
1360static void tx_cmd_local_rx_done(struct glink_transport_if *if_ptr,
1361 uint32_t lcid, uint32_t liid, bool reuse)
1362{
1363 struct command {
1364 uint16_t id;
1365 uint16_t lcid;
1366 uint32_t liid;
1367 uint64_t reserved;
1368 };
1369 struct command cmd;
1370 struct edge_info *einfo;
1371 int rcu_id;
1372
1373 memset(&cmd, 0, sizeof(cmd));
1374 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1375
1376 rcu_id = srcu_read_lock(&einfo->use_ref);
1377 if (einfo->in_ssr) {
1378 srcu_read_unlock(&einfo->use_ref, rcu_id);
1379 return;
1380 }
1381
1382 cmd.id = reuse ? RX_DONE_W_REUSE_CMD : RX_DONE_CMD;
1383 cmd.lcid = lcid;
1384 cmd.liid = liid;
1385
1386 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1387 srcu_read_unlock(&einfo->use_ref, rcu_id);
1388}
1389
1390/**
1391 * tx_cmd_rx_intent_req() - Convert an rx intent request cmd to wire format and
1392 * transmit
1393 * @if_ptr: The transport to transmit on.
1394 * @lcid: The local channel id to encode.
1395 * @size: The requested intent size to encode.
1396 *
1397 * Return: 0 on success or standard Linux error code.
1398 */
1399static int tx_cmd_rx_intent_req(struct glink_transport_if *if_ptr,
1400 uint32_t lcid, size_t size)
1401{
1402 struct command {
1403 uint16_t id;
1404 uint16_t lcid;
1405 uint32_t size;
1406 uint64_t reserved;
1407 };
1408 struct command cmd;
1409 struct edge_info *einfo;
1410 int rcu_id;
1411
1412 if (size > UINT_MAX) {
1413 pr_err("%s: size %zu is too large to encode\n", __func__, size);
1414 return -EMSGSIZE;
1415 }
1416
1417 memset(&cmd, 0, sizeof(cmd));
1418 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1419
1420 rcu_id = srcu_read_lock(&einfo->use_ref);
1421 if (einfo->in_ssr) {
1422 srcu_read_unlock(&einfo->use_ref, rcu_id);
1423 return -EFAULT;
1424 }
1425
1426 cmd.id = RX_INTENT_REQ_CMD,
1427 cmd.lcid = lcid;
1428 cmd.size = size;
1429
1430 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1431
1432 srcu_read_unlock(&einfo->use_ref, rcu_id);
1433 return 0;
1434}
1435
1436/**
1437 * tx_cmd_rx_intent_req_ack() - Convert an rx intent request ack cmd to wire
1438 * format and transmit
1439 * @if_ptr: The transport to transmit on.
1440 * @lcid: The local channel id to encode.
1441 * @granted: The request response to encode.
1442 *
1443 * Return: 0 on success or standard Linux error code.
1444 */
1445static int tx_cmd_remote_rx_intent_req_ack(struct glink_transport_if *if_ptr,
1446 uint32_t lcid, bool granted)
1447{
1448 struct command {
1449 uint16_t id;
1450 uint16_t lcid;
1451 uint32_t response;
1452 uint64_t reserved;
1453 };
1454 struct command cmd;
1455 struct edge_info *einfo;
1456 int rcu_id;
1457
1458 memset(&cmd, 0, sizeof(cmd));
1459 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1460
1461 rcu_id = srcu_read_lock(&einfo->use_ref);
1462 if (einfo->in_ssr) {
1463 srcu_read_unlock(&einfo->use_ref, rcu_id);
1464 return -EFAULT;
1465 }
1466
1467 cmd.id = RX_INTENT_REQ_ACK_CMD,
1468 cmd.lcid = lcid;
1469 if (granted)
1470 cmd.response = 1;
1471 else
1472 cmd.response = 0;
1473
1474 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1475
1476 srcu_read_unlock(&einfo->use_ref, rcu_id);
1477 return 0;
1478}
1479
1480/**
1481 * tx_cmd_set_sigs() - Convert a signals ack cmd to wire format and transmit
1482 * @if_ptr: The transport to transmit on.
1483 * @lcid: The local channel id to encode.
1484 * @sigs: The signals to encode.
1485 *
1486 * Return: 0 on success or standard Linux error code.
1487 */
1488static int tx_cmd_set_sigs(struct glink_transport_if *if_ptr, uint32_t lcid,
1489 uint32_t sigs)
1490{
1491 struct command {
1492 uint16_t id;
1493 uint16_t lcid;
1494 uint32_t sigs;
1495 uint64_t reserved;
1496 };
1497 struct command cmd;
1498 struct edge_info *einfo;
1499 int rcu_id;
1500
1501 memset(&cmd, 0, sizeof(cmd));
1502 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1503
1504 rcu_id = srcu_read_lock(&einfo->use_ref);
1505 if (einfo->in_ssr) {
1506 srcu_read_unlock(&einfo->use_ref, rcu_id);
1507 return -EFAULT;
1508 }
1509
1510 cmd.id = SIGNALS_CMD,
1511 cmd.lcid = lcid;
1512 cmd.sigs = sigs;
1513
1514 glink_spi_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
1515
1516 srcu_read_unlock(&einfo->use_ref, rcu_id);
1517 return 0;
1518}
1519
1520/**
1521 * tx_data() - convert a data/tracer_pkt to wire format and transmit
1522 * @if_ptr: The transport to transmit on.
1523 * @cmd_id: The command ID to transmit.
1524 * @lcid: The local channel id to encode.
1525 * @pctx: The data to encode.
1526 *
1527 * Return: Number of bytes written or standard Linux error code.
1528 */
1529static int tx_data(struct glink_transport_if *if_ptr, uint16_t cmd_id,
1530 uint32_t lcid, struct glink_core_tx_pkt *pctx)
1531{
1532 struct command {
1533 uint16_t id;
1534 uint16_t lcid;
1535 uint32_t riid;
1536 uint64_t reserved;
1537 uint32_t size;
1538 uint32_t size_left;
1539 uint64_t addr;
1540 };
1541 struct command cmd;
1542 struct edge_info *einfo;
1543 uint32_t size;
1544 void *data_start, *dst = NULL;
1545 size_t tx_size = 0;
1546 int rcu_id;
1547
1548 if (pctx->size < pctx->size_remaining) {
1549 GLINK_ERR("%s: size remaining exceeds size. Resetting.\n",
1550 __func__);
1551 pctx->size_remaining = pctx->size;
1552 }
1553 if (!pctx->size_remaining)
1554 return 0;
1555
1556 memset(&cmd, 0, sizeof(cmd));
1557 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1558
1559 rcu_id = srcu_read_lock(&einfo->use_ref);
1560 if (einfo->in_ssr) {
1561 srcu_read_unlock(&einfo->use_ref, rcu_id);
1562 return -EFAULT;
1563 }
1564
1565 if (cmd_id == TX_DATA_CMD) {
1566 if (pctx->size_remaining == pctx->size)
1567 cmd.id = TX_DATA_CMD;
1568 else
1569 cmd.id = TX_DATA_CONT_CMD;
1570 } else {
1571 if (pctx->size_remaining == pctx->size)
1572 cmd.id = TRACER_PKT_CMD;
1573 else
1574 cmd.id = TRACER_PKT_CONT_CMD;
1575 }
1576 cmd.lcid = lcid;
1577 cmd.riid = pctx->riid;
1578 data_start = get_tx_vaddr(pctx, pctx->size - pctx->size_remaining,
1579 &tx_size);
1580 if (unlikely(!data_start)) {
1581 GLINK_ERR("%s: invalid data_start\n", __func__);
1582 srcu_read_unlock(&einfo->use_ref, rcu_id);
1583 return -EINVAL;
1584 }
1585 if (tx_size & (XPRT_ALIGNMENT - 1))
1586 tx_size = ALIGN(tx_size - SHORT_PKT_SIZE, XPRT_ALIGNMENT);
1587 if (likely(pctx->cookie))
1588 dst = pctx->cookie + (pctx->size - pctx->size_remaining);
1589
1590 mutex_lock(&einfo->write_lock);
1591 size = glink_spi_xprt_write_avail(einfo);
1592 /* Need enough space to write the command */
1593 if (size <= sizeof(cmd)) {
1594 einfo->tx_resume_needed = true;
1595 mutex_unlock(&einfo->write_lock);
1596 srcu_read_unlock(&einfo->use_ref, rcu_id);
1597 return -EAGAIN;
1598 }
1599 cmd.addr = 0;
1600 cmd.size = tx_size;
1601 pctx->size_remaining -= tx_size;
1602 cmd.size_left = pctx->size_remaining;
1603 if (cmd.id == TRACER_PKT_CMD)
1604 tracer_pkt_log_event((void *)(pctx->data), GLINK_XPRT_TX);
1605
1606 if (!strcmp(einfo->xprt_cfg.edge, "wdsp"))
1607 wdsp_resume(&einfo->cmpnt);
1608 glink_spi_xprt_tx_data(einfo, data_start, dst, tx_size);
1609 glink_spi_xprt_tx_cmd_safe(einfo, &cmd, sizeof(cmd));
1610 GLINK_DBG("%s %s: lcid[%u] riid[%u] cmd[%d], size[%d], size_left[%d]\n",
1611 "<SPI>", __func__, cmd.lcid, cmd.riid, cmd.id, cmd.size,
1612 cmd.size_left);
1613 mutex_unlock(&einfo->write_lock);
1614 srcu_read_unlock(&einfo->use_ref, rcu_id);
1615 return cmd.size;
1616}
1617
1618/**
1619 * tx_short_data() - Tansmit a short packet in band along with command
1620 * @if_ptr: The transport to transmit on.
1621 * @cmd_id: The command ID to transmit.
1622 * @lcid: The local channel id to encode.
1623 * @pctx: The data to encode.
1624 *
1625 * Return: Number of bytes written or standard Linux error code.
1626 */
1627static int tx_short_data(struct glink_transport_if *if_ptr,
1628 uint32_t lcid, struct glink_core_tx_pkt *pctx)
1629{
1630 struct command {
1631 uint16_t id;
1632 uint16_t lcid;
1633 uint32_t riid;
1634 uint32_t size;
1635 uint32_t size_left;
1636 unsigned char data[SHORT_PKT_SIZE];
1637 };
1638 struct command cmd;
1639 struct edge_info *einfo;
1640 uint32_t size;
1641 void *data_start;
1642 size_t tx_size = 0;
1643 int rcu_id;
1644
1645 if (pctx->size < pctx->size_remaining) {
1646 GLINK_ERR("%s: size remaining exceeds size. Resetting.\n",
1647 __func__);
1648 pctx->size_remaining = pctx->size;
1649 }
1650 if (!pctx->size_remaining)
1651 return 0;
1652
1653 memset(&cmd, 0, sizeof(cmd));
1654 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1655
1656 rcu_id = srcu_read_lock(&einfo->use_ref);
1657 if (einfo->in_ssr) {
1658 srcu_read_unlock(&einfo->use_ref, rcu_id);
1659 return -EFAULT;
1660 }
1661
1662 cmd.id = TX_SHORT_DATA_CMD;
1663 cmd.lcid = lcid;
1664 cmd.riid = pctx->riid;
1665 data_start = get_tx_vaddr(pctx, pctx->size - pctx->size_remaining,
1666 &tx_size);
1667 if (unlikely(!data_start || tx_size > SHORT_PKT_SIZE)) {
1668 GLINK_ERR("%s: invalid data_start %p or tx_size %zu\n",
1669 __func__, data_start, tx_size);
1670 srcu_read_unlock(&einfo->use_ref, rcu_id);
1671 return -EINVAL;
1672 }
1673
1674 mutex_lock(&einfo->write_lock);
1675 size = glink_spi_xprt_write_avail(einfo);
1676 /* Need enough space to write the command */
1677 if (size <= sizeof(cmd)) {
1678 einfo->tx_resume_needed = true;
1679 mutex_unlock(&einfo->write_lock);
1680 srcu_read_unlock(&einfo->use_ref, rcu_id);
1681 return -EAGAIN;
1682 }
1683 cmd.size = tx_size;
1684 pctx->size_remaining -= tx_size;
1685 cmd.size_left = pctx->size_remaining;
1686 memcpy(cmd.data, data_start, tx_size);
1687 if (!strcmp(einfo->xprt_cfg.edge, "wdsp"))
1688 wdsp_resume(&einfo->cmpnt);
1689 glink_spi_xprt_tx_cmd_safe(einfo, &cmd, sizeof(cmd));
1690 GLINK_DBG("%s %s: lcid[%u] riid[%u] cmd[%d], size[%d], size_left[%d]\n",
1691 "<SPI>", __func__, cmd.lcid, cmd.riid, cmd.id, cmd.size,
1692 cmd.size_left);
1693 mutex_unlock(&einfo->write_lock);
1694 srcu_read_unlock(&einfo->use_ref, rcu_id);
1695 return cmd.size;
1696}
1697
1698/**
1699 * tx() - convert a data transmit cmd to wire format and transmit
1700 * @if_ptr: The transport to transmit on.
1701 * @lcid: The local channel id to encode.
1702 * @pctx: The data to encode.
1703 *
1704 * Return: Number of bytes written or standard Linux error code.
1705 */
1706static int tx(struct glink_transport_if *if_ptr, uint32_t lcid,
1707 struct glink_core_tx_pkt *pctx)
1708{
1709 if (pctx->size_remaining <= SHORT_PKT_SIZE)
1710 return tx_short_data(if_ptr, lcid, pctx);
1711 return tx_data(if_ptr, TX_DATA_CMD, lcid, pctx);
1712}
1713
1714/**
1715 * tx_cmd_tracer_pkt() - convert a tracer packet cmd to wire format and transmit
1716 * @if_ptr: The transport to transmit on.
1717 * @lcid: The local channel id to encode.
1718 * @pctx: The data to encode.
1719 *
1720 * Return: Number of bytes written or standard Linux error code.
1721 */
1722static int tx_cmd_tracer_pkt(struct glink_transport_if *if_ptr, uint32_t lcid,
1723 struct glink_core_tx_pkt *pctx)
1724{
1725 return tx_data(if_ptr, TRACER_PKT_CMD, lcid, pctx);
1726}
1727
1728/**
1729 * int wait_link_down() - Check status of read/write indices
1730 * @if_ptr: The transport to check
1731 *
1732 * Return: 1 if indices are all zero, 0 otherwise
1733 */
1734static int wait_link_down(struct glink_transport_if *if_ptr)
1735{
1736 return 0;
1737}
1738
1739/**
1740 * get_power_vote_ramp_time() - Get the ramp time required for the power
1741 * votes to be applied
1742 * @if_ptr: The transport interface on which power voting is requested.
1743 * @state: The power state for which ramp time is required.
1744 *
1745 * Return: The ramp time specific to the power state, standard error otherwise.
1746 */
1747static unsigned long get_power_vote_ramp_time(
1748 struct glink_transport_if *if_ptr, uint32_t state)
1749{
1750 return 0;
1751}
1752
1753/**
1754 * power_vote() - Update the power votes to meet qos requirement
1755 * @if_ptr: The transport interface on which power voting is requested.
1756 * @state: The power state for which the voting should be done.
1757 *
1758 * Return: 0 on Success, standard error otherwise.
1759 */
1760static int power_vote(struct glink_transport_if *if_ptr, uint32_t state)
1761{
1762 unsigned long flags;
1763 struct edge_info *einfo;
1764
1765 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1766 spin_lock_irqsave(&einfo->activity_lock, flags);
1767 einfo->activity_flag |= ACTIVE_TX;
1768 spin_unlock_irqrestore(&einfo->activity_lock, flags);
1769 return 0;
1770}
1771
1772/**
1773 * power_unvote() - Remove the all the power votes
1774 * @if_ptr: The transport interface on which power voting is requested.
1775 *
1776 * Return: 0 on Success, standard error otherwise.
1777 */
1778static int power_unvote(struct glink_transport_if *if_ptr)
1779{
1780 unsigned long flags;
1781 struct edge_info *einfo;
1782
1783 einfo = container_of(if_ptr, struct edge_info, xprt_if);
1784 spin_lock_irqsave(&einfo->activity_lock, flags);
1785 einfo->activity_flag &= ~ACTIVE_TX;
1786 spin_unlock_irqrestore(&einfo->activity_lock, flags);
1787 return 0;
1788}
1789
1790static int glink_wdsp_cmpnt_init(struct device *dev, void *priv_data)
1791{
1792 return 0;
1793}
1794
1795static int glink_wdsp_cmpnt_deinit(struct device *dev, void *priv_data)
1796{
1797 return 0;
1798}
1799
1800static int glink_wdsp_cmpnt_event_handler(struct device *dev,
1801 void *priv_data, enum wdsp_event_type event, void *data)
1802{
1803 struct edge_info *einfo = dev_get_drvdata(dev);
1804 struct glink_cmpnt *cmpnt = &einfo->cmpnt;
Chris Lewbb58f022017-06-27 16:54:11 -07001805 int rc = -EINVAL;
Chris Lewfa6135e2016-08-01 13:29:46 -07001806
1807 switch (event) {
1808 case WDSP_EVENT_PRE_BOOTUP:
1809 if (cmpnt && cmpnt->master_dev &&
1810 cmpnt->master_ops &&
Chris Lewbb58f022017-06-27 16:54:11 -07001811 cmpnt->master_ops->get_devops_for_cmpnt)
1812 rc = cmpnt->master_ops->get_devops_for_cmpnt(
1813 cmpnt->master_dev, WDSP_CMPNT_TRANSPORT,
1814 &einfo->spi_ops);
Chris Lewfa6135e2016-08-01 13:29:46 -07001815
Chris Lewbb58f022017-06-27 16:54:11 -07001816 if (rc)
Chris Lewfa6135e2016-08-01 13:29:46 -07001817 dev_err(dev, "%s: Failed to get transport device\n",
1818 __func__);
Chris Lewfa6135e2016-08-01 13:29:46 -07001819 break;
Karthikeyan Ramasubramaniane03039d2016-09-26 17:30:08 -06001820 case WDSP_EVENT_POST_BOOTUP:
1821 einfo->in_ssr = false;
1822 synchronize_srcu(&einfo->use_ref);
1823 /* No break here to trigger fake rx_worker */
Chris Lewfa6135e2016-08-01 13:29:46 -07001824 case WDSP_EVENT_IPC1_INTR:
Chris Lew4039ef92017-01-31 16:16:20 -08001825 kthread_queue_work(&einfo->kworker, &einfo->kwork);
Chris Lewfa6135e2016-08-01 13:29:46 -07001826 break;
Karthikeyan Ramasubramaniane03039d2016-09-26 17:30:08 -06001827 case WDSP_EVENT_PRE_SHUTDOWN:
1828 ssr(&einfo->xprt_if);
1829 break;
Chris Lewfa6135e2016-08-01 13:29:46 -07001830 default:
1831 pr_debug("%s: unhandled event %d", __func__, event);
1832 break;
1833 }
1834
1835 return 0;
1836}
1837
1838/* glink_wdsp_cmpnt_ops - Callback operations registered wtih WDSP framework */
1839static struct wdsp_cmpnt_ops glink_wdsp_cmpnt_ops = {
1840 .init = glink_wdsp_cmpnt_init,
1841 .deinit = glink_wdsp_cmpnt_deinit,
1842 .event_handler = glink_wdsp_cmpnt_event_handler,
1843};
1844
1845static int glink_component_bind(struct device *dev, struct device *master,
1846 void *data)
1847{
1848 struct edge_info *einfo = dev_get_drvdata(dev);
1849 struct glink_cmpnt *cmpnt = &einfo->cmpnt;
1850 int ret = 0;
1851
1852 cmpnt->master_dev = master;
1853 cmpnt->master_ops = data;
1854
1855 if (cmpnt->master_ops && cmpnt->master_ops->register_cmpnt_ops)
1856 ret = cmpnt->master_ops->register_cmpnt_ops(master, dev, einfo,
1857 &glink_wdsp_cmpnt_ops);
1858 else
1859 ret = -EINVAL;
1860
1861 if (ret)
1862 dev_err(dev, "%s: register_cmpnt_ops failed, err = %d\n",
1863 __func__, ret);
1864 return ret;
1865}
1866
1867static void glink_component_unbind(struct device *dev, struct device *master,
1868 void *data)
1869{
1870 struct edge_info *einfo = dev_get_drvdata(dev);
1871 struct glink_cmpnt *cmpnt = &einfo->cmpnt;
1872
1873 cmpnt->master_dev = NULL;
1874 cmpnt->master_ops = NULL;
1875}
1876
1877static const struct component_ops glink_component_ops = {
1878 .bind = glink_component_bind,
1879 .unbind = glink_component_unbind,
1880};
1881
1882/**
1883 * init_xprt_if() - Initialize the xprt_if for an edge
1884 * @einfo: The edge to initialize.
1885 */
1886static void init_xprt_if(struct edge_info *einfo)
1887{
1888 einfo->xprt_if.tx_cmd_version = tx_cmd_version;
1889 einfo->xprt_if.tx_cmd_version_ack = tx_cmd_version_ack;
1890 einfo->xprt_if.set_version = set_version;
1891 einfo->xprt_if.tx_cmd_ch_open = tx_cmd_ch_open;
1892 einfo->xprt_if.tx_cmd_ch_close = tx_cmd_ch_close;
1893 einfo->xprt_if.tx_cmd_ch_remote_open_ack = tx_cmd_ch_remote_open_ack;
1894 einfo->xprt_if.tx_cmd_ch_remote_close_ack = tx_cmd_ch_remote_close_ack;
1895 einfo->xprt_if.ssr = ssr;
1896 einfo->xprt_if.allocate_rx_intent = allocate_rx_intent;
1897 einfo->xprt_if.deallocate_rx_intent = deallocate_rx_intent;
1898 einfo->xprt_if.tx_cmd_local_rx_intent = tx_cmd_local_rx_intent;
1899 einfo->xprt_if.tx_cmd_local_rx_done = tx_cmd_local_rx_done;
1900 einfo->xprt_if.tx = tx;
1901 einfo->xprt_if.tx_cmd_rx_intent_req = tx_cmd_rx_intent_req;
1902 einfo->xprt_if.tx_cmd_remote_rx_intent_req_ack =
1903 tx_cmd_remote_rx_intent_req_ack;
1904 einfo->xprt_if.tx_cmd_set_sigs = tx_cmd_set_sigs;
1905 einfo->xprt_if.wait_link_down = wait_link_down;
1906 einfo->xprt_if.tx_cmd_tracer_pkt = tx_cmd_tracer_pkt;
1907 einfo->xprt_if.get_power_vote_ramp_time = get_power_vote_ramp_time;
1908 einfo->xprt_if.power_vote = power_vote;
1909 einfo->xprt_if.power_unvote = power_unvote;
1910}
1911
1912/**
1913 * init_xprt_cfg() - Initialize the xprt_cfg for an edge
1914 * @einfo: The edge to initialize.
1915 * @name: The name of the remote side this edge communicates to.
1916 */
1917static void init_xprt_cfg(struct edge_info *einfo, const char *name)
1918{
1919 einfo->xprt_cfg.name = XPRT_NAME;
1920 einfo->xprt_cfg.edge = name;
1921 einfo->xprt_cfg.versions = versions;
1922 einfo->xprt_cfg.versions_entries = ARRAY_SIZE(versions);
1923 einfo->xprt_cfg.max_cid = SZ_64K;
1924 einfo->xprt_cfg.max_iid = SZ_2G;
1925}
1926
1927/**
1928 * parse_qos_dt_params() - Parse the power states from DT
1929 * @dev: Reference to the platform device for a specific edge.
1930 * @einfo: Edge information for the edge probe function is called.
1931 *
1932 * Return: 0 on success, standard error code otherwise.
1933 */
1934static int parse_qos_dt_params(struct device_node *node,
1935 struct edge_info *einfo)
1936{
1937 int rc;
1938 int i;
1939 char *key;
1940 uint32_t *arr32;
1941 uint32_t num_states;
1942
1943 key = "qcom,ramp-time";
1944 if (!of_find_property(node, key, &num_states))
1945 return -ENODEV;
1946
1947 num_states /= sizeof(uint32_t);
1948
1949 einfo->num_pw_states = num_states;
1950
1951 arr32 = kmalloc_array(num_states, sizeof(uint32_t), GFP_KERNEL);
1952 if (!arr32)
1953 return -ENOMEM;
1954
1955 einfo->ramp_time_us = kmalloc_array(num_states, sizeof(unsigned long),
1956 GFP_KERNEL);
1957 if (!einfo->ramp_time_us) {
1958 rc = -ENOMEM;
1959 goto mem_alloc_fail;
1960 }
1961
1962 rc = of_property_read_u32_array(node, key, arr32, num_states);
1963 if (rc) {
1964 rc = -ENODEV;
1965 goto invalid_key;
1966 }
1967 for (i = 0; i < num_states; i++)
1968 einfo->ramp_time_us[i] = arr32[i];
1969
1970 kfree(arr32);
1971 return 0;
1972
1973invalid_key:
1974 kfree(einfo->ramp_time_us);
1975mem_alloc_fail:
1976 kfree(arr32);
1977 return rc;
1978}
1979
1980/**
1981 * parse_qos_dt_params() - Parse any remote FIFO configuration
1982 * @node: Reference to the platform device for a specific edge.
1983 * @einfo: Edge information for the edge probe function is called.
1984 *
1985 * Return: 0 on success, standard error code otherwise.
1986 */
1987static int parse_remote_fifo_cfg(struct device_node *node,
1988 struct edge_info *einfo)
1989{
1990 int rc;
1991 char *key;
1992
1993 key = "qcom,out-read-idx-reg";
1994 rc = of_property_read_u32(node, key, &einfo->tx_fifo_read_reg_addr);
1995 if (rc)
1996 goto key_error;
1997
1998 key = "qcom,out-write-idx-reg";
1999 rc = of_property_read_u32(node, key, &einfo->tx_fifo_write_reg_addr);
2000 if (rc)
2001 goto key_error;
2002
2003 key = "qcom,in-read-idx-reg";
2004 rc = of_property_read_u32(node, key, &einfo->rx_fifo_read_reg_addr);
2005 if (rc)
2006 goto key_error;
2007
2008 key = "qcom,in-write-idx-reg";
2009 rc = of_property_read_u32(node, key, &einfo->rx_fifo_write_reg_addr);
2010 if (rc)
2011 goto key_error;
2012 return 0;
2013
2014key_error:
2015 pr_err("%s: Error %d parsing key %s\n", __func__, rc, key);
2016 return rc;
2017}
2018
2019static int glink_spi_probe(struct platform_device *pdev)
2020{
2021 struct device_node *node;
2022 struct device_node *phandle_node;
2023 struct edge_info *einfo;
2024 int rc;
2025 char *key;
2026 const char *subsys_name;
2027 unsigned long flags;
2028
2029 node = pdev->dev.of_node;
2030
2031 einfo = kzalloc(sizeof(*einfo), GFP_KERNEL);
2032 if (!einfo) {
2033 rc = -ENOMEM;
2034 goto edge_info_alloc_fail;
2035 }
2036
2037 key = "label";
2038 subsys_name = of_get_property(node, key, NULL);
2039 if (!subsys_name) {
2040 pr_err("%s: missing key %s\n", __func__, key);
2041 rc = -ENODEV;
2042 goto missing_key;
2043 }
2044 strlcpy(einfo->subsys_name, subsys_name, sizeof(einfo->subsys_name));
2045
2046 init_xprt_cfg(einfo, subsys_name);
2047 init_xprt_if(einfo);
2048
Chris Lewfa6135e2016-08-01 13:29:46 -07002049 einfo->fifo_size = DEFAULT_FIFO_SIZE;
Chris Lew4039ef92017-01-31 16:16:20 -08002050 kthread_init_work(&einfo->kwork, rx_worker);
2051 kthread_init_worker(&einfo->kworker);
Chris Lewfa6135e2016-08-01 13:29:46 -07002052 init_srcu_struct(&einfo->use_ref);
2053 mutex_init(&einfo->write_lock);
2054 init_waitqueue_head(&einfo->tx_blocked_queue);
2055 spin_lock_init(&einfo->activity_lock);
2056
2057 spin_lock_irqsave(&edge_infos_lock, flags);
2058 list_add_tail(&einfo->list, &edge_infos);
2059 spin_unlock_irqrestore(&edge_infos_lock, flags);
2060
2061 einfo->task = kthread_run(kthread_worker_fn, &einfo->kworker,
2062 "spi_%s", subsys_name);
2063 if (IS_ERR(einfo->task)) {
2064 rc = PTR_ERR(einfo->task);
2065 pr_err("%s: kthread run failed %d\n", __func__, rc);
2066 goto kthread_fail;
2067 }
2068
2069 key = "qcom,remote-fifo-config";
2070 phandle_node = of_parse_phandle(node, key, 0);
2071 if (phandle_node)
2072 parse_remote_fifo_cfg(phandle_node, einfo);
2073
2074 key = "qcom,qos-config";
2075 phandle_node = of_parse_phandle(node, key, 0);
2076 if (phandle_node && !(of_get_glink_core_qos_cfg(phandle_node,
2077 &einfo->xprt_cfg)))
2078 parse_qos_dt_params(node, einfo);
2079
2080 rc = glink_core_register_transport(&einfo->xprt_if, &einfo->xprt_cfg);
2081 if (rc == -EPROBE_DEFER)
2082 goto reg_xprt_fail;
2083 if (rc) {
2084 pr_err("%s: glink core register transport failed: %d\n",
2085 __func__, rc);
2086 goto reg_xprt_fail;
2087 }
2088
2089 dev_set_drvdata(&pdev->dev, einfo);
2090 if (!strcmp(einfo->xprt_cfg.edge, "wdsp")) {
2091 rc = component_add(&pdev->dev, &glink_component_ops);
2092 if (rc) {
2093 pr_err("%s: component_add failed, err = %d\n",
2094 __func__, rc);
2095 rc = -ENODEV;
2096 goto reg_cmpnt_fail;
2097 }
2098 }
2099 return 0;
2100
2101reg_cmpnt_fail:
2102 dev_set_drvdata(&pdev->dev, NULL);
2103 glink_core_unregister_transport(&einfo->xprt_if);
2104reg_xprt_fail:
Chris Lew4039ef92017-01-31 16:16:20 -08002105 kthread_flush_worker(&einfo->kworker);
Chris Lewfa6135e2016-08-01 13:29:46 -07002106 kthread_stop(einfo->task);
2107 einfo->task = NULL;
2108kthread_fail:
2109 spin_lock_irqsave(&edge_infos_lock, flags);
2110 list_del(&einfo->list);
2111 spin_unlock_irqrestore(&edge_infos_lock, flags);
2112missing_key:
2113 kfree(einfo);
2114edge_info_alloc_fail:
2115 return rc;
2116}
2117
2118static int glink_spi_remove(struct platform_device *pdev)
2119{
2120 struct edge_info *einfo;
2121 unsigned long flags;
2122
2123 einfo = (struct edge_info *)dev_get_drvdata(&pdev->dev);
2124 glink_core_unregister_transport(&einfo->xprt_if);
Chris Lew4039ef92017-01-31 16:16:20 -08002125 kthread_flush_worker(&einfo->kworker);
Chris Lewfa6135e2016-08-01 13:29:46 -07002126 kthread_stop(einfo->task);
2127 einfo->task = NULL;
2128 spin_lock_irqsave(&edge_infos_lock, flags);
2129 list_del(&einfo->list);
2130 spin_unlock_irqrestore(&edge_infos_lock, flags);
2131 kfree(einfo);
2132 return 0;
2133}
2134
2135static int glink_spi_resume(struct platform_device *pdev)
2136{
2137 return 0;
2138}
2139
2140static int glink_spi_suspend(struct platform_device *pdev,
2141 pm_message_t state)
2142{
2143 unsigned long flags;
2144 struct edge_info *einfo;
2145 bool suspend;
2146 int rc = -EBUSY;
2147
2148 einfo = (struct edge_info *)dev_get_drvdata(&pdev->dev);
2149 if (strcmp(einfo->xprt_cfg.edge, "wdsp"))
2150 return 0;
2151
2152 spin_lock_irqsave(&einfo->activity_lock, flags);
2153 suspend = !(einfo->activity_flag);
2154 spin_unlock_irqrestore(&einfo->activity_lock, flags);
2155 if (suspend)
2156 rc = wdsp_suspend(&einfo->cmpnt);
2157 if (rc < 0)
2158 pr_err("%s: Could not suspend activity_flag %d, rc %d\n",
2159 __func__, einfo->activity_flag, rc);
2160 return rc;
2161}
2162
2163static const struct of_device_id spi_match_table[] = {
2164 { .compatible = "qcom,glink-spi-xprt" },
2165 {},
2166};
2167
2168static struct platform_driver glink_spi_driver = {
2169 .probe = glink_spi_probe,
2170 .remove = glink_spi_remove,
2171 .resume = glink_spi_resume,
2172 .suspend = glink_spi_suspend,
2173 .driver = {
2174 .name = "msm_glink_spi_xprt",
2175 .owner = THIS_MODULE,
2176 .of_match_table = spi_match_table,
2177 },
2178};
2179
2180static int __init glink_spi_xprt_init(void)
2181{
2182 int rc;
2183
2184 rc = platform_driver_register(&glink_spi_driver);
2185 if (rc)
2186 pr_err("%s: glink_spi register failed %d\n", __func__, rc);
2187
2188 return rc;
2189}
2190module_init(glink_spi_xprt_init);
2191
2192static void __exit glink_spi_xprt_exit(void)
2193{
2194 platform_driver_unregister(&glink_spi_driver);
2195}
2196module_exit(glink_spi_xprt_exit);
2197
2198MODULE_DESCRIPTION("MSM G-Link SPI Transport");
2199MODULE_LICENSE("GPL v2");