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